#ifndef HELPINGCAT_H #define HELPINGCAT_H struct HelpingCat : public GameObject { vector active; vector reload; vector models; bool update_needed; float radius = 4.0; HelpingCat() : GameObject("HelpingCat") {} static vec3 input_transform(float x, float y, float z){ return vec3(x*2, z*2, y*2); } bool init() override { init_from_object("cube.obj", input_transform); setup_shaders("model_vertex.glsl", "cube_fragment.glsl"); vertex_attrib = glGetAttribLocation(program, "in_vertex"); tex_attrib = glGetAttribLocation(program, "in_texcoord"); mvp_uniform = glGetUniformLocation(program, "vp"); tex_uniform = glGetUniformLocation(program, "tex"); setup_texture("cat.jpg"); setup_locations(); return true; } void draw(mat4 vp) override { glUseProgram(program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glUniform1i(tex_uniform, 0); glUniformMatrix4fv(mvp_uniform, 1, 0, glm::value_ptr(vp)); glEnableVertexAttribArray(vertex_attrib); glBindBuffer(GL_ARRAY_BUFFER, vbuf); glVertexAttribPointer(vertex_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(tex_attrib); glBindBuffer(GL_ARRAY_BUFFER, tbuf); glVertexAttribPointer(tex_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, lbuf); if(update_needed){ glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(mat4) * models.size(), models.data(), GL_STATIC_DRAW); update_needed = false; } glDrawElementsInstanced(GL_TRIANGLES, element_count, GL_UNSIGNED_INT, 0, locations.size()); } bool update_locations() override { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lbuf); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mat4) * models.size(), models.data(), GL_STATIC_DRAW); return true; } void add(float x, float y, float z){ locations.push_back(vec4(x, y, z, 0)); active.push_back(false); reload.push_back(0); models.push_back(translate(mat4(1.0), vec3(x, y, z))); } void activate(float x, float y, float z){ int contact = in_contact(x, y, z); if(contact != -1) active[contact] = !active[contact]; } void movement(){ for(auto go : objects){ if(!go->hostile) continue; if(!go->locations.size()) continue; vec4 target_loc = go->locations[0]; for(int i = 0; i < locations.size(); i++){ if(!active[i]) continue; models[i] = rotate(models[i], 0.02f, vec3(0, 1, 0)); update_needed = true; reload[i]--; if(reload[i] <= 0){ printf("Active cat! Firing\n"); vec3 tv3 = 0.5f * normalize(vec3(target_loc.x - locations[i].x, target_loc.y - locations[i].y, target_loc.z - locations[i].z)); projectiles->addnew_direct(locations[i], vec4(tv3.x, tv3.y, tv3.z, 400.0f)); reload[i] = 20; } } } } }; #endif