~ubuntu-branches/ubuntu/raring/glmark2/raring

« back to all changes in this revision

Viewing changes to src/scene-texture.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo
  • Date: 2012-08-21 15:38:09 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120821153809-bwux72bat8qp2n5v
Tags: 2012.08-0ubuntu1
* New upstream release 2012.08 (LP: #1039736)
  - Avoid crashing if gl used is not >= 2.0 (LP: #842279)
* Bumping dh compatibility level to v9
* debian/control:
  - Update Standards-Version to 3.9.3.
  - Add libjpeg-dev build dependency.
  - Use libegl1-x11-dev as an build-dep alternative instead of libegl1-dev.
  - Update description of glmark2-data binary package.
* debian/copyright:
  - Refresh copyright based on the current upstrem version
* debian/rules:
  - Clean compiled python code from unpacked waflib/ directory, as
    described in http://wiki.debian.org/UnpackWaf

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 * Authors:
21
21
 *  Ben Smith (original glmark benchmark)
22
22
 *  Alexandros Frantzis (glmark2)
 
23
 *  Jesse Barker (glmark2)
23
24
 */
24
25
#include "scene.h"
25
26
#include "mat.h"
28
29
#include "log.h"
29
30
#include "program.h"
30
31
#include "shader-source.h"
31
 
 
 
32
#include "texture.h"
 
33
#include "model.h"
 
34
#include "util.h"
32
35
#include <cmath>
33
36
 
 
37
using LibMatrix::vec3;
 
38
using std::string;
 
39
 
34
40
SceneTexture::SceneTexture(Canvas &pCanvas) :
35
 
    Scene(pCanvas, "texture")
 
41
    Scene(pCanvas, "texture"), radius_(0.0),
 
42
    orientModel_(false), orientationAngle_(0.0)
36
43
{
37
 
    mOptions["texture-filter"] = Scene::Option("texture-filter", "nearest",
38
 
                                               "[nearest, linear, mipmap]");
 
44
    const ModelMap& modelMap = Model::find_models();
 
45
    string optionValues;
 
46
    for (ModelMap::const_iterator modelIt = modelMap.begin();
 
47
         modelIt != modelMap.end();
 
48
         modelIt++)
 
49
    {
 
50
        static bool doSeparator(false);
 
51
        if (doSeparator)
 
52
        {
 
53
            optionValues += ",";
 
54
        }
 
55
        const std::string& curName = modelIt->first;
 
56
        optionValues += curName;
 
57
        doSeparator = true;
 
58
    }
 
59
    options_["model"] = Scene::Option("model", "cube", "Which model to use",
 
60
                                      optionValues);
 
61
    options_["texture-filter"] = Scene::Option("texture-filter", "nearest",
 
62
                                               "The texture filter to use",
 
63
                                               "nearest,linear,linear-shader,mipmap");
 
64
    optionValues = "";
 
65
    const TextureMap& textureMap = Texture::find_textures();
 
66
    for (TextureMap::const_iterator textureIt = textureMap.begin();
 
67
         textureIt != textureMap.end();
 
68
         textureIt++)
 
69
    {
 
70
        static bool doSeparator(false);
 
71
        if (doSeparator)
 
72
        {
 
73
            optionValues += ",";
 
74
        }
 
75
        const std::string& curName = textureIt->first;
 
76
        optionValues += curName;
 
77
        doSeparator = true;
 
78
    }
 
79
    options_["texture"] = Scene::Option("texture", "crate-base", "Which texture to use",
 
80
                                        optionValues);
 
81
    options_["texgen"] = Scene::Option("texgen", "false",
 
82
                                       "Whether to generate texcoords in the shader",
 
83
                                       "false,true");
39
84
}
40
85
 
41
86
SceneTexture::~SceneTexture()
42
87
{
43
88
}
44
89
 
45
 
int SceneTexture::load()
46
 
{
47
 
    Model model;
48
 
 
49
 
    if(!model.load_3ds(GLMARK_DATA_PATH"/models/cube.3ds"))
50
 
        return 0;
51
 
 
52
 
    model.calculate_normals();
53
 
    model.convert_to_mesh(mCubeMesh);
54
 
    mCubeMesh.build_vbo();
55
 
 
56
 
    mRotationSpeed = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
57
 
 
58
 
    mRunning = false;
59
 
 
60
 
    return 1;
61
 
}
62
 
 
63
 
void SceneTexture::unload()
64
 
{
65
 
    mCubeMesh.reset();
66
 
}
67
 
 
68
 
void SceneTexture::setup()
69
 
{
70
 
    Scene::setup();
71
 
 
72
 
    // Load shaders
 
90
bool
 
91
SceneTexture::load()
 
92
{
 
93
    rotationSpeed_ = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
 
94
 
 
95
    running_ = false;
 
96
 
 
97
    return true;
 
98
}
 
99
 
 
100
void
 
101
SceneTexture::unload()
 
102
{
 
103
    mesh_.reset();
 
104
}
 
105
 
 
106
bool
 
107
SceneTexture::setup()
 
108
{
 
109
    if (!Scene::setup())
 
110
        return false;
 
111
 
73
112
    static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
 
113
    static const std::string vtx_shader_texgen_filename(GLMARK_DATA_PATH"/shaders/light-basic-texgen.vert");
74
114
    static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex.frag");
 
115
    static const std::string frg_shader_bilinear_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex-bilinear.frag");
75
116
    static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
76
117
    static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
77
 
    ShaderSource vtx_source(vtx_shader_filename);
78
 
    ShaderSource frg_source(frg_shader_filename);
79
 
 
80
 
    // Add constants to shaders
81
 
    vtx_source.add_const("LightSourcePosition", lightPosition);
82
 
    vtx_source.add_const("MaterialDiffuse", materialDiffuse);
83
 
 
84
 
    if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
85
 
                                          frg_source.str()))
86
 
    {
87
 
        return;
88
 
    }
89
 
 
90
 
    std::vector<GLint> attrib_locations;
91
 
    attrib_locations.push_back(mProgram["position"].location());
92
 
    attrib_locations.push_back(mProgram["normal"].location());
93
 
    attrib_locations.push_back(mProgram["texcoord"].location());
94
 
    mCubeMesh.set_attrib_locations(attrib_locations);
95
118
 
96
119
    // Create texture according to selected filtering
97
120
    GLint min_filter = GL_NONE;
98
121
    GLint mag_filter = GL_NONE;
99
 
    const std::string &filter = mOptions["texture-filter"].value;
 
122
    const std::string &filter = options_["texture-filter"].value;
100
123
 
101
124
    if (filter == "nearest") {
102
125
        min_filter = GL_NEAREST;
106
129
        min_filter = GL_LINEAR;
107
130
        mag_filter = GL_LINEAR;
108
131
    }
 
132
    else if (filter == "linear-shader") {
 
133
        min_filter = GL_NEAREST;
 
134
        mag_filter = GL_NEAREST;
 
135
    }
109
136
    else if (filter == "mipmap") {
110
137
        min_filter = GL_LINEAR_MIPMAP_LINEAR;
111
138
        mag_filter = GL_LINEAR;
112
139
    }
113
140
 
114
 
    Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &mTexture,
115
 
                  min_filter, mag_filter, 0);
116
 
 
117
 
    mProgram.start();
118
 
 
119
 
    mCurrentFrame = 0;
120
 
    mRotation = LibMatrix::vec3();
121
 
    mRunning = true;
122
 
    mStartTime = Scene::get_timestamp_us() / 1000000.0;
123
 
    mLastUpdateTime = mStartTime;
 
141
    const string& whichTexture(options_["texture"].value);
 
142
    if (!Texture::load(whichTexture, &texture_, min_filter, mag_filter, 0))
 
143
        return false;
 
144
 
 
145
    // Load shaders
 
146
    bool doTexGen(options_["texgen"].value == "true");
 
147
    ShaderSource vtx_source;
 
148
    if (doTexGen) {
 
149
        vtx_source.append_file(vtx_shader_texgen_filename);
 
150
        vtx_source.add_const("PI", static_cast<float>(M_PI));
 
151
    }
 
152
    else {
 
153
        vtx_source.append_file(vtx_shader_filename);
 
154
    }
 
155
    ShaderSource frg_source;
 
156
    if (filter == "linear-shader") {
 
157
        frg_source.append_file(frg_shader_bilinear_filename);
 
158
        LibMatrix::vec2 texture_size(512, 512);
 
159
        frg_source.add_const("TextureSize", texture_size);
 
160
    }
 
161
    else {
 
162
        frg_source.append_file(frg_shader_filename);
 
163
    }
 
164
 
 
165
    // Add constants to shaders
 
166
    vtx_source.add_const("LightSourcePosition", lightPosition);
 
167
    vtx_source.add_const("MaterialDiffuse", materialDiffuse);
 
168
 
 
169
    if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
 
170
                                          frg_source.str()))
 
171
    {
 
172
        return false;
 
173
    }
 
174
 
 
175
    Model model;
 
176
    const string& whichModel(options_["model"].value);
 
177
    bool modelLoaded = model.load(whichModel);
 
178
    if(!modelLoaded)
 
179
        return false;
 
180
 
 
181
    // Now that we're successfully loaded, there are a few quirks about
 
182
    // some of the known models that we need to account for.  The draw
 
183
    // logic for the scene wants to rotate the model around the Y axis.
 
184
    // Most of our models are described this way.  Some need adjustment
 
185
    // (an additional rotation that gets the model into the correct
 
186
    // orientation).
 
187
    //
 
188
    // Here's a summary:
 
189
    //
 
190
    // Angel rotates around the Y axis
 
191
    // Armadillo rotates around the Y axis
 
192
    // Buddha rotates around the X axis
 
193
    // Bunny rotates around the Y axis
 
194
    // Dragon rotates around the X axis
 
195
    // Horse rotates around the Y axis
 
196
    if (whichModel == "buddha" || whichModel == "dragon")
 
197
    {
 
198
        orientModel_ = true;
 
199
        orientationAngle_ = -90.0;
 
200
        orientationVec_ = vec3(1.0, 0.0, 0.0);
 
201
    }
 
202
    else if (whichModel == "armadillo")
 
203
    {
 
204
        orientModel_ = true;
 
205
        orientationAngle_ = 180.0; 
 
206
        orientationVec_ = vec3(0.0, 1.0, 0.0);
 
207
    }
 
208
 
 
209
    if (model.needTexcoords())
 
210
        model.calculate_texcoords();
 
211
    model.calculate_normals();
 
212
    // Tell the converter which attributes we care about
 
213
    std::vector<std::pair<Model::AttribType, int> > attribs;
 
214
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
 
215
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
 
216
    if (!doTexGen) {
 
217
        attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTexcoord, 2));
 
218
    }
 
219
    model.convert_to_mesh(mesh_, attribs);
 
220
    mesh_.build_vbo();
 
221
 
 
222
    // Calculate a projection matrix that is a good fit for the model
 
223
    vec3 maxVec = model.maxVec();
 
224
    vec3 minVec = model.minVec();
 
225
    vec3 diffVec = maxVec - minVec;
 
226
    centerVec_ = maxVec + minVec;
 
227
    centerVec_ /= 2.0;
 
228
    float diameter = diffVec.length();
 
229
    radius_ = diameter / 2;
 
230
    float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
 
231
    fovy /= M_PI;
 
232
    fovy *= 180.0;
 
233
    float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
 
234
    perspective_.setIdentity();
 
235
    perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);
 
236
 
 
237
    program_.start();
 
238
 
 
239
    std::vector<GLint> attrib_locations;
 
240
    attrib_locations.push_back(program_["position"].location());
 
241
    attrib_locations.push_back(program_["normal"].location());
 
242
    if (doTexGen) {
 
243
        program_["CenterPoint"] = centerVec_;
 
244
    }
 
245
    else {
 
246
        attrib_locations.push_back(program_["texcoord"].location());
 
247
    }
 
248
    mesh_.set_attrib_locations(attrib_locations);
 
249
 
 
250
    currentFrame_ = 0;
 
251
    rotation_ = LibMatrix::vec3();
 
252
    running_ = true;
 
253
    startTime_ = Util::get_timestamp_us() / 1000000.0;
 
254
    lastUpdateTime_ = startTime_;
 
255
 
 
256
    return true;
124
257
}
125
258
 
126
 
void SceneTexture::teardown()
 
259
void
 
260
SceneTexture::teardown()
127
261
{
128
 
    mProgram.stop();
129
 
    mProgram.release();
 
262
    program_.stop();
 
263
    program_.release();
130
264
 
131
 
    glDeleteTextures(1, &mTexture);
 
265
    glDeleteTextures(1, &texture_);
132
266
 
133
267
    Scene::teardown();
134
268
}
135
269
 
136
 
void SceneTexture::update()
 
270
void
 
271
SceneTexture::update()
137
272
{
138
 
    double current_time = Scene::get_timestamp_us() / 1000000.0;
139
 
    double dt = current_time - mLastUpdateTime;
140
 
    double elapsed_time = current_time - mStartTime;
141
 
 
142
 
    mLastUpdateTime = current_time;
143
 
 
144
 
    if (elapsed_time >= mDuration) {
145
 
        mAverageFPS = mCurrentFrame / elapsed_time;
146
 
        mRunning = false;
147
 
    }
148
 
 
149
 
    mRotation += mRotationSpeed * dt;
150
 
 
151
 
    mCurrentFrame++;
 
273
    Scene::update();
 
274
 
 
275
    double elapsed_time = lastUpdateTime_ - startTime_;
 
276
 
 
277
    rotation_ = rotationSpeed_ * elapsed_time;
152
278
}
153
279
 
154
 
void SceneTexture::draw()
 
280
void
 
281
SceneTexture::draw()
155
282
{
156
283
    // Load the ModelViewProjectionMatrix uniform in the shader
157
284
    LibMatrix::Stack4 model_view;
158
 
    LibMatrix::mat4 model_view_proj(mCanvas.projection());
159
 
 
160
 
    model_view.translate(0.0f, 0.0f, -5.0f);
161
 
    model_view.rotate(mRotation.x(), 1.0f, 0.0f, 0.0f);
162
 
    model_view.rotate(mRotation.y(), 0.0f, 1.0f, 0.0f);
163
 
    model_view.rotate(mRotation.z(), 0.0f, 0.0f, 1.0f);
 
285
    model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.5 + radius_));
 
286
    model_view.rotate(rotation_.x(), 1.0f, 0.0f, 0.0f);
 
287
    model_view.rotate(rotation_.y(), 0.0f, 1.0f, 0.0f);
 
288
    model_view.rotate(rotation_.z(), 0.0f, 0.0f, 1.0f);
 
289
    if (orientModel_)
 
290
    {
 
291
        model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
 
292
    }
 
293
    LibMatrix::mat4 model_view_proj(perspective_);
164
294
    model_view_proj *= model_view.getCurrent();
165
295
 
166
 
    mProgram["ModelViewProjectionMatrix"] = model_view_proj;
 
296
    program_["ModelViewProjectionMatrix"] = model_view_proj;
167
297
 
168
298
    // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
169
299
    // inverse transpose of the model view matrix.
170
300
    LibMatrix::mat4 normal_matrix(model_view.getCurrent());
171
301
    normal_matrix.inverse().transpose();
172
 
    mProgram["NormalMatrix"] = normal_matrix;
 
302
    program_["NormalMatrix"] = normal_matrix;
173
303
 
174
304
    glActiveTexture(GL_TEXTURE0);
175
 
    glBindTexture(GL_TEXTURE_2D, mTexture);
 
305
    glBindTexture(GL_TEXTURE_2D, texture_);
176
306
 
177
 
    mCubeMesh.render_vbo();
 
307
    mesh_.render_vbo();
178
308
}
179
309
 
180
310
Scene::ValidationResult
181
311
SceneTexture::validate()
182
312
{
183
 
    static const double radius_3d(std::sqrt(3.0));
 
313
    static const double radius_3d(std::sqrt(3 * 2.0 * 2.0));
184
314
 
185
 
    if (mRotation.x() != 0 || mRotation.y() != 0 || mRotation.z() != 0)
 
315
    if (rotation_.x() != 0 || rotation_.y() != 0 || rotation_.z() != 0)
186
316
        return Scene::ValidationUnknown;
187
317
 
188
318
    Canvas::Pixel ref;
189
319
 
190
 
    Canvas::Pixel pixel = mCanvas.read_pixel(mCanvas.width() / 2 + 3,
191
 
                                             mCanvas.height() / 2 + 3);
 
320
    Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 2 + 3,
 
321
                                             canvas_.height() / 2 + 3);
192
322
 
193
 
    const std::string &filter = mOptions["texture-filter"].value;
 
323
    const std::string &filter = options_["texture-filter"].value;
194
324
 
195
325
    if (filter == "nearest")
196
 
        ref = Canvas::Pixel(0x3b, 0x3a, 0x39, 0xff);
 
326
        ref = Canvas::Pixel(0x2b, 0x2a, 0x28, 0xff);
197
327
    else if (filter == "linear")
198
 
        ref = Canvas::Pixel(0x36, 0x36, 0x34, 0xff);
 
328
        ref = Canvas::Pixel(0x2b, 0x2a, 0x28, 0xff);
 
329
    else if (filter == "linear-shader")
 
330
        ref = Canvas::Pixel(0x2d, 0x2c, 0x2a, 0xff);
199
331
    else if (filter == "mipmap")
200
 
        ref = Canvas::Pixel(0x35, 0x35, 0x34, 0xff);
 
332
        ref = Canvas::Pixel(0x2c, 0x2d, 0x2a, 0xff);
201
333
    else
202
334
        return Scene::ValidationUnknown;
203
335
 
204
 
    double dist = pixel_value_distance(pixel, ref);
 
336
    double dist = pixel.distance_rgb(ref);
205
337
 
206
338
    if (dist < radius_3d + 0.01) {
207
339
        return Scene::ValidationSuccess;