Changeset 0d5c100 in opengl-game for new-game.cpp


Ignore:
Timestamp:
Jun 1, 2018, 2:22:13 AM (6 years ago)
Author:
Dmitry Portnoy <dmp1488@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
f7d35da
Parents:
e3ca955
Message:

Create a populateBuffers() function to encapsulate populating all the OpenGL data buffers using for rendering objects in the scene given a list of those objects.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • new-game.cpp

    re3ca955 r0d5c100  
    3232#include <vector>
    3333#include <queue>
     34#include <map>
    3435
    3536using namespace std;
     
    6364
    6465const bool FULLSCREEN = false;
    65 const bool SHOW_FPS = false;
    66 const bool DISABLE_VSYNC = true;
     66const bool SHOW_FPS = true;
     67const bool DISABLE_VSYNC = true; // disable vsync to see real framerate
    6768unsigned int MAX_UNIFORMS = 0; // Requires OpenGL constants only available at runtime
    6869
     
    8182
    8283SceneObject* clickedObject = NULL;
    83 SceneObject* selectedObject;
     84SceneObject* selectedObject = NULL;
    8485
    8586float NEAR_CLIP = 0.1f;
     
    106107
    107108void addObjectToScene(SceneObject& obj);
     109void populateBuffers(vector<SceneObject>& objects,
     110                     GLuint* points_vbo,
     111                     GLuint* colors_vbo,
     112                     GLuint* selected_colors_vbo,
     113                     GLuint* texcoords_vbo,
     114                     GLuint* normals_vbo,
     115                     GLuint* ubo,
     116                     GLuint* model_mat_idx_vbo,
     117                     map<GLuint, unsigned int>& shaderCounts,
     118                     map<GLuint, unsigned int>& curShaderBase);
    108119
    109120void renderMainMenu();
     
    115126                  GLuint points_vbo, GLuint normals_vbo,
    116127                  GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
    117                   SceneObject* selectedObject);
     128                  SceneObject* selectedObject,
     129                  map<GLuint, unsigned int>& shaderCounts,
     130                  map<GLuint, unsigned int>& curShaderBase);
    118131void renderSceneGui();
    119132
     
    173186   * for every 1024 objects and then draws all those objects with one glDraw call.
    174187   *
    175    * Since I'm currently drawing all my objects dynamically (i.e switcing the shaders they use),
    176    * I'll table the implementation of this algorithm until I have a reasonable number of objects always using the same shader
     188   * Since I currently have very few objects, I'll wait to implement this  until I have
     189   * a reasonable number of objects always using the same shader.
    177190   */
    178191
     
    232245   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    233246
    234    // I can create a vbo to store all points for all models,
    235    // and another vbo to store all colors for all models, but how do I allow alternating between
    236    // using colors and textures for each model?
    237    // Do I create a third vbo for texture coordinates and change which vertex attribute array I have bound
    238    // when I want to draw a textured model?
    239    // Or do I create one vao with vertices and colors and another with vertices and textures and switch between the two?
    240    // Since I would have to switch shader programs to toggle between using colors or textures,
    241    // I think I should use one vao for both cases and have a points vbo, a colors vbo, and a textures vbo
    242    // One program will use the points and colors, and the other will use the points and texture coords
    243    // Review how to bind vbos to vertex attributes in the shader.
    244    //
    245    // Binding vbos is done using glVertexAttribPointer(...) on a per-vao basis and is not tied to any specific shader.
    246    // This means, I could create two vaos, one for each shader and have one use points+colors, while the other
    247    // uses points+texxcoords.
    248    //
    249    // At some point, when I have lots of objects, I want to group them by shader when drawing them.
    250    // I'd probably create some sort of set per shader and have each set contain the ids of all objects currently using that shader
    251    // Most likely, I'd want to implement each set using a bit field. Makes it constant time for updates and iterating through them
    252    // should not be much of an issue either.
    253    // Assuming making lots of draw calls instead of one is not innefficient, I should be fine.
    254    // I might also want to use one glDrawElements call per shader to draw multiple non-memory-adjacent models
    255    //
    256    // DECISION: Use a glDrawElements call per shader since I use a regular array to specify the elements to draw
    257    // Actually, this will only work once I get UBOs working since each object will have a different model matrix
    258    // For now, I could implement this with a glDrawElements call per object and update the model uniform for each object
     247   /* RENDERING ALGORITHM
     248    *
     249    * Create a separate vbo for each of the following things:
     250    * - points
     251    * - colors
     252    * - texture coordinates
     253    * - selected colors
     254    * - normals
     255    * - indices into a ubo that stores a model matrix for each object
     256    *
     257    * Also, make a model matrix ubo, the entirety of which will be passed to the vertex shader.
     258    * The vbo containing the correct index into the ubo (mentioned above) will be used to select
     259    * the right model matrix for each point. The index in the vbo will be the saem for all points
     260    * of any given object.
     261    *
     262    * There will be two shader programs for now, one for draing colored objects, and another for
     263    * drawing textured ones. The points, normals, and model mat ubo indices will be passed to both
     264    * shaders, while the colors vbo will only be passed to the colors shader, and the texcoords vbo
     265    * only to the texture shader.
     266    *
     267    * Right now, the currently selected object is drawn using one color (specified in the selected
     268    * colors vbo) regardless of whether it is normally rendering using colors or a texture. The selected
     269    * object is rendering by binding the selected colors vbo in place of the colors vbo and using the colors
     270    * shader. Then, the selected object is redrawn along with all other objects, but the depth buffer test
     271    * prevents the unselected version of the object from appearing on the screen. This lets me render all the
     272    * objects that use a particular shader using one glDrawArrays() call.
     273    */
    259274
    260275   GLuint color_sp = loadShaderProgram("./color.vert", "./color.frag");
     
    393408   GLsizeiptr offset;
    394409
    395    GLsizeiptr points_buffer_size = 0;
    396    GLsizeiptr textures_buffer_size = 0;
    397    GLsizeiptr ubo_buffer_size = 0;
    398    GLsizeiptr model_mat_idx_buffer_size = 0;
    399 
    400    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    401       points_buffer_size += obj_it->points.size() * sizeof(GLfloat);
    402       textures_buffer_size += obj_it->texcoords.size() * sizeof(GLfloat);
    403       ubo_buffer_size += 16 * sizeof(GLfloat);
    404       model_mat_idx_buffer_size += obj_it->num_points * sizeof(GLuint);
    405    }
    406 
    407    GLuint points_vbo = 0;
    408    glGenBuffers(1, &points_vbo);
    409    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
    410    glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
    411 
    412    offset = 0;
    413    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    414       glBufferSubData(GL_ARRAY_BUFFER, offset, obj_it->points.size() * sizeof(GLfloat), &obj_it->points[0]);
    415       offset += obj_it->points.size() * sizeof(GLfloat);
    416    }
    417 
    418    GLuint colors_vbo = 0;
    419    glGenBuffers(1, &colors_vbo);
    420    glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
    421    glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
    422 
    423    offset = 0;
    424    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    425       glBufferSubData(GL_ARRAY_BUFFER, offset, obj_it->colors.size() * sizeof(GLfloat), &obj_it->colors[0]);
    426       offset += obj_it->colors.size() * sizeof(GLfloat);
    427    }
    428 
    429    GLuint selected_colors_vbo = 0;
    430    glGenBuffers(1, &selected_colors_vbo);
    431    glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
    432    glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
    433 
    434    offset = 0;
    435    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    436       glBufferSubData(GL_ARRAY_BUFFER, offset, obj_it->selected_colors.size() * sizeof(GLfloat), &obj_it->selected_colors[0]);
    437       offset += obj_it->selected_colors.size() * sizeof(GLfloat);
    438    }
    439 
    440    GLuint texcoords_vbo = 0;
    441    glGenBuffers(1, &texcoords_vbo);
    442    glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
    443    glBufferData(GL_ARRAY_BUFFER, textures_buffer_size, NULL, GL_DYNAMIC_DRAW);
    444 
    445    offset = 0;
    446    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    447       glBufferSubData(GL_ARRAY_BUFFER, offset, obj_it->texcoords.size() * sizeof(GLfloat), &obj_it->texcoords[0]);
    448       offset += obj_it->texcoords.size() * sizeof(GLfloat);
    449    }
    450 
    451    GLuint normals_vbo = 0;
    452    glGenBuffers(1, &normals_vbo);
    453    glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
    454    glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
    455 
    456    offset = 0;
    457    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    458       glBufferSubData(GL_ARRAY_BUFFER, offset, obj_it->normals.size() * sizeof(GLfloat), &obj_it->normals[0]);
    459       offset += obj_it->normals.size() * sizeof(GLfloat);
    460    }
    461    glBindBuffer(GL_UNIFORM_BUFFER, 0);
    462 
    463    GLuint ubo = 0;
    464    glGenBuffers(1, &ubo);
    465    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    466    glBufferData(GL_UNIFORM_BUFFER, ubo_buffer_size, NULL, GL_DYNAMIC_DRAW);
    467 
    468    offset = 0;
    469    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    470       glBufferSubData(GL_UNIFORM_BUFFER, offset, sizeof(obj_it->model_mat), value_ptr(obj_it->model_mat));
    471       offset += sizeof(obj_it->model_mat);
    472    }
    473    glBindBuffer(GL_UNIFORM_BUFFER, 0);
    474 
    475    GLuint model_mat_idx_vbo = 0;
    476    glGenBuffers(1, &model_mat_idx_vbo);
    477    glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
    478    glBufferData(GL_ARRAY_BUFFER, model_mat_idx_buffer_size, NULL, GL_DYNAMIC_DRAW);
    479 
    480    offset = 0;
    481    unsigned int idx = 0;
    482    for (obj_it = objects.begin(); obj_it != objects.end(); obj_it++) {
    483       for (int i = 0; i < obj_it->num_points; i++) {
    484          glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(GLuint), &idx);
    485          offset += sizeof(GLuint);
    486       }
    487       idx++;
    488    }
     410   GLuint points_vbo, colors_vbo, selected_colors_vbo, texcoords_vbo,
     411      normals_vbo, ubo, model_mat_idx_vbo;
     412
     413   map<GLuint, unsigned int> shaderCounts, curShaderBase;
     414
     415   populateBuffers(objects,
     416                  &points_vbo,
     417                  &colors_vbo,
     418                  &selected_colors_vbo,
     419                  &texcoords_vbo,
     420                  &normals_vbo,
     421                  &ubo,
     422                  &model_mat_idx_vbo,
     423                  shaderCounts,
     424                  curShaderBase);
    489425
    490426   GLuint vao = 0;
     
    593529   //glPolygonMode(GL_FRONT, GL_LINE);
    594530
    595    // disable vsync to see real framerate
    596531   if (DISABLE_VSYNC && SHOW_FPS) {
    597532      glfwSwapInterval(0);
     
    670605               points_vbo, normals_vbo,
    671606               colors_vbo, texcoords_vbo, selected_colors_vbo,
    672                selectedObject);
     607               selectedObject,
     608               shaderCounts, curShaderBase);
    673609            renderSceneGui();
    674610            break;
     
    762698      SceneObject* closest_object = NULL;
    763699
    764       SceneObject* obj;
    765700      for (vector<SceneObject>::iterator it = objects.begin(); it != objects.end(); it++) {
    766          obj = &*it;
    767 
    768701         for (unsigned int p_idx = 0; p_idx < it->points.size(); p_idx += 9) {
    769             if (faceClicked({
    770                vec3(it->points[p_idx], it->points[p_idx + 1], it->points[p_idx + 2]),
    771                vec3(it->points[p_idx + 3], it->points[p_idx + 4], it->points[p_idx + 5]),
    772                vec3(it->points[p_idx + 6], it->points[p_idx + 7], it->points[p_idx + 8]),
     702            if (faceClicked(
     703               {
     704                  vec3(it->points[p_idx], it->points[p_idx + 1], it->points[p_idx + 2]),
     705                  vec3(it->points[p_idx + 3], it->points[p_idx + 4], it->points[p_idx + 5]),
     706                  vec3(it->points[p_idx + 6], it->points[p_idx + 7], it->points[p_idx + 8]),
    773707               },
    774                obj, ray_world, cam_pos_temp, click_point)) {
     708               &*it, ray_world, cam_pos_temp, click_point
     709            )) {
    775710               click_point = view_mat * click_point;
    776711
    777712               if (-NEAR_CLIP >= click_point.z && click_point.z > -FAR_CLIP && click_point.z > closest_point.z) {
    778713                  closest_point = click_point.xyz();
    779                   closest_object = obj;
     714                  closest_object = &*it;
    780715               }
    781716            }
     
    926861}
    927862
    928 // The easiest thing here seems to be to set all the colors we want in a CPU array once per frame,
    929 // them copy it over to the GPU and make one draw call
    930 // This method also easily allows us to use any colors we want for each shape.
    931 // Try to compare the frame times for the current method and the new one
    932 //
    933 // Alternatively, I have one large color buffer that has selected and unselected colors
    934 // Then, when I know which object is selected, I can use glVertexAttribPointer to decide
    935 // whether to use the selected or unselected color for it
    936 
    937 // I'll have to think of the best way to do something similar when using
    938 // one draw call. Probably, in that case, I'll use one draw call for all unselectable objects
    939 // and use the approach mentioned above for all selectable objects.
    940 // I can have one colors vbo for unselectable objects and another for selected+unselected colors
    941 // of selectable objects
    942 
    943 // For both colored and textured objects, using a single draw call will only work for objects
    944 // that don't change state (i.e. don't change colors or switch from colored to textured).
    945 
    946 // This means I'll probably have one call for static colored objects, one call for static textured objects,
    947 // a loop of calls for dynamic currently colored objects, and a loop of calls for dynamic currently textured objects.
    948 // This will increase if I add new shaders since I'll need either one new call or one new loop of calls per shader
     863void addObjectToScene(SceneObject& obj) {
     864   obj.id = objects.size(); // currently unused
     865   obj.num_points = obj.points.size() / 3;
     866
     867   obj.normals.reserve(obj.points.size());
     868   for (int i = 0; i < obj.points.size(); i += 9) {
     869      vec3 point1 = vec3(obj.points[i], obj.points[i + 1], obj.points[i + 2]);
     870      vec3 point2 = vec3(obj.points[i + 3], obj.points[i + 4], obj.points[i + 5]);
     871      vec3 point3 = vec3(obj.points[i + 6], obj.points[i + 7], obj.points[i + 8]);
     872
     873      vec3 normal = normalize(cross(point2 - point1, point3 - point1));
     874
     875      // Add the same normal for all 3 points
     876      for (int j = 0; j < 3; j++) {
     877         obj.normals.push_back(normal.x);
     878         obj.normals.push_back(normal.y);
     879         obj.normals.push_back(normal.z);
     880      }
     881   }
     882
     883   objects.push_back(obj);
     884}
     885
     886void populateBuffers(vector<SceneObject>& objects,
     887                     GLuint* points_vbo,
     888                     GLuint* colors_vbo,
     889                     GLuint* selected_colors_vbo,
     890                     GLuint* texcoords_vbo,
     891                     GLuint* normals_vbo,
     892                     GLuint* ubo,
     893                     GLuint* model_mat_idx_vbo,
     894                     map<GLuint, unsigned int>& shaderCounts,
     895                     map<GLuint, unsigned int>& curShaderBase) {
     896   GLsizeiptr points_buffer_size = 0;
     897   GLsizeiptr textures_buffer_size = 0;
     898   GLsizeiptr ubo_buffer_size = 0;
     899   GLsizeiptr model_mat_idx_buffer_size = 0;
     900
     901   map<GLuint, unsigned int> curShaderOffset;
     902
     903   map<GLuint, unsigned int> shaderUboCounts;
     904   map<GLuint, unsigned int> curShaderUboBase;
     905   map<GLuint, unsigned int> curShaderUboOffset;
     906
     907   vector<SceneObject>::iterator it;
     908
     909   /* Find all shaders that need to be used and  the number of objects and
     910    * number of points for each shader. Construct a map from shader id to count
     911    * of points being drawn using that shader (for thw model matrix ubo, we
     912    * need object counts instead). These will be used to get offsets into the
     913    * vertex buffer for each shader.
     914    */
     915   for (it = objects.begin(); it != objects.end(); it++) {
     916      points_buffer_size += it->points.size() * sizeof(GLfloat);
     917      textures_buffer_size += it->texcoords.size() * sizeof(GLfloat);
     918      ubo_buffer_size += 16 * sizeof(GLfloat);
     919      model_mat_idx_buffer_size += it->num_points * sizeof(GLuint);
     920
     921      if (shaderCounts.count(it->shader_program) == 0) {
     922         shaderCounts[it->shader_program] = it->num_points;
     923         shaderUboCounts[it->shader_program] = 1;
     924      } else {
     925         shaderCounts[it->shader_program] += it->num_points;
     926         shaderUboCounts[it->shader_program]++;
     927      }
     928   }
     929
     930   map<GLuint, unsigned int>::iterator shaderIt;
     931   unsigned int lastShaderCount = 0;
     932   unsigned int lastShaderUboCount = 0;
     933
     934   /*
     935    * The counts calculated above can be used to get the starting offset of
     936    * each shader in the vertex buffer. Create a map of base offsets to mark
     937    * where the data for the first object using a given shader begins. Also,
     938    * create a map of current offsets to mark where to copy data for the next
     939    * object being added.
     940    */
     941   cout << "Shader counts:" << endl;
     942   for (shaderIt = shaderCounts.begin(); shaderIt != shaderCounts.end(); shaderIt++) {
     943      curShaderOffset[shaderIt->first] = 0;
     944      curShaderUboOffset[shaderIt->first] = 0;
     945
     946      curShaderBase[shaderIt->first] = lastShaderCount;
     947      lastShaderCount += shaderCounts[shaderIt->first];
     948
     949      curShaderUboBase[shaderIt->first] = lastShaderUboCount;
     950      lastShaderUboCount += shaderUboCounts[shaderIt->first];
     951   }
     952
     953   // Initialize all the buffers using the counts calculated above
     954
     955   *points_vbo = 0;
     956   glGenBuffers(1, points_vbo);
     957   glBindBuffer(GL_ARRAY_BUFFER, *points_vbo);
     958   glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
     959
     960   *colors_vbo = 0;
     961   glGenBuffers(1, colors_vbo);
     962   glBindBuffer(GL_ARRAY_BUFFER, *colors_vbo);
     963   glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
     964
     965   *selected_colors_vbo = 0;
     966   glGenBuffers(1, selected_colors_vbo);
     967   glBindBuffer(GL_ARRAY_BUFFER, *selected_colors_vbo);
     968   glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
     969
     970   *texcoords_vbo = 0;
     971   glGenBuffers(1, texcoords_vbo);
     972   glBindBuffer(GL_ARRAY_BUFFER, *texcoords_vbo);
     973   glBufferData(GL_ARRAY_BUFFER, textures_buffer_size, NULL, GL_DYNAMIC_DRAW);
     974
     975   *normals_vbo = 0;
     976   glGenBuffers(1, normals_vbo);
     977   glBindBuffer(GL_ARRAY_BUFFER, *normals_vbo);
     978   glBufferData(GL_ARRAY_BUFFER, points_buffer_size, NULL, GL_DYNAMIC_DRAW);
     979
     980   *ubo = 0;
     981   glGenBuffers(1, ubo);
     982   glBindBuffer(GL_UNIFORM_BUFFER, *ubo);
     983   glBufferData(GL_UNIFORM_BUFFER, ubo_buffer_size, NULL, GL_DYNAMIC_DRAW);
     984
     985   *model_mat_idx_vbo = 0;
     986   glGenBuffers(1, model_mat_idx_vbo);
     987   glBindBuffer(GL_ARRAY_BUFFER, *model_mat_idx_vbo);
     988   glBufferData(GL_ARRAY_BUFFER, model_mat_idx_buffer_size, NULL, GL_DYNAMIC_DRAW);
     989
     990   GLint vertex_ubo_offset;
     991   for (it = objects.begin(); it != objects.end(); it++) {
     992      it->vertex_vbo_offset = curShaderBase[it->shader_program] + curShaderOffset[it->shader_program];
     993      vertex_ubo_offset = curShaderUboBase[it->shader_program] + curShaderUboOffset[it->shader_program];
     994
     995      glBindBuffer(GL_ARRAY_BUFFER, *points_vbo);
     996      glBufferSubData(GL_ARRAY_BUFFER, it->vertex_vbo_offset * sizeof(GLfloat) * 3, it->points.size() * sizeof(GLfloat), &it->points[0]);
     997
     998      glBindBuffer(GL_ARRAY_BUFFER, *colors_vbo);
     999      glBufferSubData(GL_ARRAY_BUFFER, it->vertex_vbo_offset * sizeof(GLfloat) * 3, it->colors.size() * sizeof(GLfloat), &it->colors[0]);
     1000
     1001      glBindBuffer(GL_ARRAY_BUFFER, *selected_colors_vbo);
     1002      glBufferSubData(GL_ARRAY_BUFFER, it->vertex_vbo_offset * sizeof(GLfloat) * 3, it->selected_colors.size() * sizeof(GLfloat), &it->selected_colors[0]);
     1003
     1004      glBindBuffer(GL_ARRAY_BUFFER, *texcoords_vbo);
     1005      glBufferSubData(GL_ARRAY_BUFFER, it->vertex_vbo_offset * sizeof(GLfloat) * 2, it->texcoords.size() * sizeof(GLfloat), &it->texcoords[0]);
     1006
     1007      glBindBuffer(GL_ARRAY_BUFFER, *normals_vbo);
     1008      glBufferSubData(GL_ARRAY_BUFFER, it->vertex_vbo_offset * sizeof(GLfloat) * 3, it->normals.size() * sizeof(GLfloat), &it->normals[0]);
     1009
     1010      glBindBuffer(GL_ARRAY_BUFFER, *model_mat_idx_vbo);
     1011      for (int i = 0; i < it->num_points; i++) {
     1012         glBufferSubData(GL_ARRAY_BUFFER, (it->vertex_vbo_offset + i) * sizeof(GLuint), sizeof(GLuint), &vertex_ubo_offset);
     1013      }
     1014
     1015      curShaderOffset[it->shader_program] += it->num_points;
     1016
     1017      glBindBuffer(GL_UNIFORM_BUFFER, *ubo);
     1018      glBufferSubData(GL_UNIFORM_BUFFER, vertex_ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(it->model_mat));
     1019
     1020      curShaderUboOffset[it->shader_program]++;
     1021   }
     1022}
    9491023
    9501024void renderScene(vector<SceneObject>& objects,
     
    9531027                  GLuint points_vbo, GLuint normals_vbo,
    9541028                  GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
    955                   SceneObject* selectedObject) {
    956 
    957    vector<int> colored_objs, selected_objs, textured_objs;
    958 
    959    // group scene objects by shader and vbo
    960    for (unsigned int i = 0; i < objects.size(); i++) {
    961       if (selectedObject == &objects[i]) {
    962          selected_objs.push_back(i);
    963       }
    964       if (objects[i].shader_program == color_sp) {
    965          colored_objs.push_back(i);
    966       } else if (objects[i].shader_program == texture_sp) {
    967          textured_objs.push_back(i);
    968       }
    969    }
    970 
    971    vector<int>::iterator it;
     1029                  SceneObject* selectedObject,
     1030                  map<GLuint, unsigned int>& shaderCounts,
     1031                  map<GLuint, unsigned int>& curShaderBase) {
    9721032
    9731033   glUseProgram(color_sp);
    9741034   glBindVertexArray(vao1);
    9751035
    976    glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
    977    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
    978 
    979    for (it = selected_objs.begin(); it != selected_objs.end(); it++) {
    980       glDrawArrays(GL_TRIANGLES, objects[*it].vertex_vbo_offset, objects[*it].num_points);
     1036   if (selectedObject != NULL) {
     1037      glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
     1038      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
     1039
     1040      glDrawArrays(GL_TRIANGLES, selectedObject->vertex_vbo_offset, selectedObject->num_points);
    9811041   }
    9821042
     
    9841044   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
    9851045
    986    for (it = colored_objs.begin(); it != colored_objs.end(); it++) {
    987       glDrawArrays(GL_TRIANGLES, objects[*it].vertex_vbo_offset, objects[*it].num_points);
    988    }
     1046   glDrawArrays(GL_TRIANGLES, curShaderBase[color_sp], shaderCounts[color_sp]);
    9891047
    9901048   glUseProgram(texture_sp);
    9911049   glBindVertexArray(vao2);
    9921050
    993    for (it = textured_objs.begin(); it != textured_objs.end(); it++) {
    994       glDrawArrays(GL_TRIANGLES, objects[*it].vertex_vbo_offset, objects[*it].num_points);
    995    }
     1051   glDrawArrays(GL_TRIANGLES, curShaderBase[texture_sp], shaderCounts[texture_sp]);
    9961052}
    9971053
     
    10511107}
    10521108
    1053 void addObjectToScene(SceneObject& obj) {
    1054    obj.id = objects.size(); // currently unused
    1055    obj.num_points = obj.points.size() / 3;
    1056 
    1057    static GLint vbo_offset = 0;
    1058    obj.vertex_vbo_offset = vbo_offset;
    1059    vbo_offset += obj.num_points;
    1060 
    1061    obj.normals.reserve(obj.points.size());
    1062    for (int i = 0; i < obj.points.size(); i += 9) {
    1063       vec3 point1 = vec3(obj.points[i], obj.points[i+1], obj.points[i + 2]);
    1064       vec3 point2 = vec3(obj.points[i+3], obj.points[i + 4], obj.points[i + 5]);
    1065       vec3 point3 = vec3(obj.points[i+6], obj.points[i + 7], obj.points[i + 8]);
    1066 
    1067       vec3 normal = normalize(cross(point2 - point1, point3 - point1));
    1068 
    1069       // Add the same normal for all 3 points
    1070       for (int j = 0; j < 3; j++) {
    1071          obj.normals.push_back(normal.x);
    1072          obj.normals.push_back(normal.y);
    1073          obj.normals.push_back(normal.z);
    1074       }
    1075    }
    1076 
    1077    objects.push_back(obj);
    1078 }
    1079 
    10801109void renderMainMenu() {
    10811110}
Note: See TracChangeset for help on using the changeset viewer.