Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //--------------------------------------------------------------------------------
     18 // TeapotRenderer.cpp
     19 // Render a teapot
     20 //--------------------------------------------------------------------------------
     21 //--------------------------------------------------------------------------------
     22 // Include files
     23 //--------------------------------------------------------------------------------
     24 #include "TeapotRenderer.h"
     25 
     26 //--------------------------------------------------------------------------------
     27 // Teapot model data
     28 //--------------------------------------------------------------------------------
     29 #include "teapot.inl"
     30 
     31 //--------------------------------------------------------------------------------
     32 // Ctor
     33 //--------------------------------------------------------------------------------
     34 TeapotRenderer::TeapotRenderer()
     35 {
     36 
     37 }
     38 
     39 //--------------------------------------------------------------------------------
     40 // Dtor
     41 //--------------------------------------------------------------------------------
     42 TeapotRenderer::~TeapotRenderer()
     43 {
     44     Unload();
     45 }
     46 
     47 void TeapotRenderer::Init()
     48 {
     49     //Settings
     50     glFrontFace( GL_CCW );
     51 
     52     //Load shader
     53     LoadShaders( &shader_param_, "Shaders/VS_ShaderPlain.vsh",
     54             "Shaders/ShaderPlain.fsh" );
     55 
     56     //Create Index buffer
     57     num_indices_ = sizeof(teapotIndices) / sizeof(teapotIndices[0]);
     58     glGenBuffers( 1, &ibo_ );
     59     glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );
     60     glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(teapotIndices), teapotIndices,
     61             GL_STATIC_DRAW );
     62     glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
     63 
     64     //Create VBO
     65     num_vertices_ = sizeof(teapotPositions) / sizeof(teapotPositions[0]) / 3;
     66     int32_t iStride = sizeof(TEAPOT_VERTEX);
     67     int32_t iIndex = 0;
     68     TEAPOT_VERTEX* p = new TEAPOT_VERTEX[num_vertices_];
     69     for( int32_t i = 0; i < num_vertices_; ++i )
     70     {
     71         p[i].pos[0] = teapotPositions[iIndex];
     72         p[i].pos[1] = teapotPositions[iIndex + 1];
     73         p[i].pos[2] = teapotPositions[iIndex + 2];
     74 
     75         p[i].normal[0] = teapotNormals[iIndex];
     76         p[i].normal[1] = teapotNormals[iIndex + 1];
     77         p[i].normal[2] = teapotNormals[iIndex + 2];
     78         iIndex += 3;
     79     }
     80     glGenBuffers( 1, &vbo_ );
     81     glBindBuffer( GL_ARRAY_BUFFER, vbo_ );
     82     glBufferData( GL_ARRAY_BUFFER, iStride * num_vertices_, p, GL_STATIC_DRAW );
     83     glBindBuffer( GL_ARRAY_BUFFER, 0 );
     84 
     85     delete[] p;
     86 
     87     UpdateViewport();
     88     mat_model_ = ndk_helper::Mat4::Translation( 0, 0, -15.f );
     89 
     90     ndk_helper::Mat4 mat = ndk_helper::Mat4::RotationX( M_PI / 3 );
     91     mat_model_ = mat * mat_model_;
     92 }
     93 
     94 void TeapotRenderer::UpdateViewport()
     95 {
     96     //Init Projection matrices
     97     int32_t viewport[4];
     98     glGetIntegerv( GL_VIEWPORT, viewport );
     99     float fAspect = (float) viewport[2] / (float) viewport[3];
    100 
    101     const float CAM_NEAR = 5.f;
    102     const float CAM_FAR = 10000.f;
    103     bool bRotate = false;
    104     mat_projection_ = ndk_helper::Mat4::Perspective( fAspect, 1.f, CAM_NEAR, CAM_FAR );
    105 }
    106 
    107 void TeapotRenderer::Unload()
    108 {
    109     if( vbo_ )
    110     {
    111         glDeleteBuffers( 1, &vbo_ );
    112         vbo_ = 0;
    113     }
    114 
    115     if( ibo_ )
    116     {
    117         glDeleteBuffers( 1, &ibo_ );
    118         ibo_ = 0;
    119     }
    120 
    121     if( shader_param_.program_ )
    122     {
    123         glDeleteProgram( shader_param_.program_ );
    124         shader_param_.program_ = 0;
    125     }
    126 }
    127 
    128 void TeapotRenderer::Update( float fTime )
    129 {
    130     const float CAM_X = 0.f;
    131     const float CAM_Y = 0.f;
    132     const float CAM_Z = 700.f;
    133 
    134     mat_view_ = ndk_helper::Mat4::LookAt( ndk_helper::Vec3( CAM_X, CAM_Y, CAM_Z ),
    135             ndk_helper::Vec3( 0.f, 0.f, 0.f ), ndk_helper::Vec3( 0.f, 1.f, 0.f ) );
    136 
    137     if( camera_ )
    138     {
    139         camera_->Update();
    140         mat_view_ = camera_->GetTransformMatrix() * mat_view_
    141                 * camera_->GetRotationMatrix() * mat_model_;
    142     }
    143     else
    144     {
    145         mat_view_ = mat_view_ * mat_model_;
    146     }
    147 }
    148 
    149 void TeapotRenderer::Render()
    150 {
    151     //
    152     // Feed Projection and Model View matrices to the shaders
    153     ndk_helper::Mat4 mat_vp = mat_projection_ * mat_view_;
    154 
    155     // Bind the VBO
    156     glBindBuffer( GL_ARRAY_BUFFER, vbo_ );
    157 
    158     int32_t iStride = sizeof(TEAPOT_VERTEX);
    159     // Pass the vertex data
    160     glVertexAttribPointer( ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, iStride,
    161             BUFFER_OFFSET( 0 ) );
    162     glEnableVertexAttribArray( ATTRIB_VERTEX );
    163 
    164     glVertexAttribPointer( ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, iStride,
    165             BUFFER_OFFSET( 3 * sizeof(GLfloat) ) );
    166     glEnableVertexAttribArray( ATTRIB_NORMAL );
    167 
    168     // Bind the IB
    169     glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );
    170 
    171     glUseProgram( shader_param_.program_ );
    172 
    173     TEAPOT_MATERIALS material = { { 1.0f, 0.5f, 0.5f }, { 1.0f, 1.0f, 1.0f, 10.f }, {
    174             0.1f, 0.1f, 0.1f }, };
    175 
    176     //Update uniforms
    177     glUniform4f( shader_param_.material_diffuse_, material.diffuse_color[0],
    178             material.diffuse_color[1], material.diffuse_color[2], 1.f );
    179 
    180     glUniform4f( shader_param_.material_specular_, material.specular_color[0],
    181             material.specular_color[1], material.specular_color[2],
    182             material.specular_color[3] );
    183     //
    184     //using glUniform3fv here was troublesome
    185     //
    186     glUniform3f( shader_param_.material_ambient_, material.ambient_color[0],
    187             material.ambient_color[1], material.ambient_color[2] );
    188 
    189     glUniformMatrix4fv( shader_param_.matrix_projection_, 1, GL_FALSE, mat_vp.Ptr() );
    190     glUniformMatrix4fv( shader_param_.matrix_view_, 1, GL_FALSE, mat_view_.Ptr() );
    191     glUniform3f( shader_param_.light0_, 100.f, -200.f, -600.f );
    192 
    193     glDrawElements( GL_TRIANGLES, num_indices_, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0) );
    194 
    195     glBindBuffer( GL_ARRAY_BUFFER, 0 );
    196     glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
    197 }
    198 
    199 bool TeapotRenderer::LoadShaders( SHADER_PARAMS* params,
    200         const char* strVsh,
    201         const char* strFsh )
    202 {
    203     GLuint program;
    204     GLuint vert_shader, frag_shader;
    205     char *vert_shader_pathname, *frag_shader_pathname;
    206 
    207     // Create shader program
    208     program = glCreateProgram();
    209     LOGI( "Created Shader %d", program );
    210 
    211     // Create and compile vertex shader
    212     if( !ndk_helper::shader::CompileShader( &vert_shader, GL_VERTEX_SHADER, strVsh ) )
    213     {
    214         LOGI( "Failed to compile vertex shader" );
    215         glDeleteProgram( program );
    216         return false;
    217     }
    218 
    219     // Create and compile fragment shader
    220     if( !ndk_helper::shader::CompileShader( &frag_shader, GL_FRAGMENT_SHADER, strFsh ) )
    221     {
    222         LOGI( "Failed to compile fragment shader" );
    223         glDeleteProgram( program );
    224         return false;
    225     }
    226 
    227     // Attach vertex shader to program
    228     glAttachShader( program, vert_shader );
    229 
    230     // Attach fragment shader to program
    231     glAttachShader( program, frag_shader );
    232 
    233     // Bind attribute locations
    234     // this needs to be done prior to linking
    235     glBindAttribLocation( program, ATTRIB_VERTEX, "myVertex" );
    236     glBindAttribLocation( program, ATTRIB_NORMAL, "myNormal" );
    237     glBindAttribLocation( program, ATTRIB_UV, "myUV" );
    238 
    239     // Link program
    240     if( !ndk_helper::shader::LinkProgram( program ) )
    241     {
    242         LOGI( "Failed to link program: %d", program );
    243 
    244         if( vert_shader )
    245         {
    246             glDeleteShader( vert_shader );
    247             vert_shader = 0;
    248         }
    249         if( frag_shader )
    250         {
    251             glDeleteShader( frag_shader );
    252             frag_shader = 0;
    253         }
    254         if( program )
    255         {
    256             glDeleteProgram( program );
    257         }
    258 
    259         return false;
    260     }
    261 
    262     // Get uniform locations
    263     params->matrix_projection_ = glGetUniformLocation( program, "uPMatrix" );
    264     params->matrix_view_ = glGetUniformLocation( program, "uMVMatrix" );
    265 
    266     params->light0_ = glGetUniformLocation( program, "vLight0" );
    267     params->material_diffuse_ = glGetUniformLocation( program, "vMaterialDiffuse" );
    268     params->material_ambient_ = glGetUniformLocation( program, "vMaterialAmbient" );
    269     params->material_specular_ = glGetUniformLocation( program, "vMaterialSpecular" );
    270 
    271     // Release vertex and fragment shaders
    272     if( vert_shader )
    273         glDeleteShader( vert_shader );
    274     if( frag_shader )
    275         glDeleteShader( frag_shader );
    276 
    277     params->program_ = program;
    278     return true;
    279 }
    280 
    281 bool TeapotRenderer::Bind( ndk_helper::TapCamera* camera )
    282 {
    283     camera_ = camera;
    284     return true;
    285 }
    286 
    287