diff options
author | iamn1ck <iamn1ck@yahoo.com> | 2017-02-19 07:00:34 -0600 |
---|---|---|
committer | Tom Barrett <tombarrett@siu.edu> | 2017-03-07 13:22:46 -0600 |
commit | 74c6854fd8dcbaee736ac0421805ff1e03c4a1e2 (patch) | |
tree | 4a3ae40bea9b07a2111128e98d9272bdbac2af87 /src | |
parent | 03885192b9ff7d3c5e2dcfd98aefd21e9b62f603 (diff) |
-quadtree and opengl rendering are now in the master branch !
-using sdl_rect for location and size ended up being not so great due to it not having floats, so we reverted back to using location
-much, much refractoring is now needed
Diffstat (limited to 'src')
-rw-r--r-- | src/creature.cpp | 103 | ||||
-rw-r--r-- | src/entity.cpp | 17 | ||||
-rw-r--r-- | src/geoshader.cpp | 115 | ||||
-rw-r--r-- | src/list.cpp | 78 | ||||
-rw-r--r-- | src/main.cpp | 59 | ||||
-rw-r--r-- | src/quadtree.cpp | 140 | ||||
-rw-r--r-- | src/rectdrawer.cpp | 135 | ||||
-rw-r--r-- | src/resource.cpp | 20 | ||||
-rw-r--r-- | src/spritebatch.cpp | 185 | ||||
-rw-r--r-- | src/window.cpp | 40 |
10 files changed, 767 insertions, 125 deletions
diff --git a/src/creature.cpp b/src/creature.cpp index bd731d2..0484fd1 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1,16 +1,19 @@ #include "creature.hpp" -Creature::Creature(Window M, SDL_Rect R, Dna D) +Creature::Creature(Location t, Dna D) { - renderer = M.getRenderer(); - rect = R; + L = t; mine = D; - if(rect.x == 0 && rect.y == 0){ - rect.x = rand()%WINDOW_X; - rect.y = rand()%WINDOW_Y; + if(L.x == 0 && L.y == 0){ + L.x = -30.0 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30-(-30)))); + L.y = -30.0 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30-(-30)))); } + gfxData.sides = 4.0; + gfxData.x = L.x; + gfxData.y = L.y; + type = CREATURE_TYPE; health = mine.maxHealth/2; gender = rand() % 2; @@ -19,6 +22,22 @@ Creature::Creature(Window M, SDL_Rect R, Dna D) pregnancyReady = false; pregnate = false; hasTarget = false; + + if(gender){ + gfxData.r = 1.0; + gfxData.g = 0.0; + gfxData.b = 0.0; + } + else if(pregnate){ + gfxData.r = 1.0; + gfxData.g = 0.0; + gfxData.b = 1.0; + } + else{ + gfxData.r = 0.0; + gfxData.g = 0.0; + gfxData.b = 1.0; + } } void Creature::Behavior() @@ -59,8 +78,8 @@ void Creature::Priority() void Creature::setTarget() { - std::random_shuffle(N.begin(),N.end()); - for(std::vector <Entity*>::iterator it = N.begin(); it!=N.end(); it++){ + //std::random_shuffle(N.begin(),N.end()); + for(std::list <Entity*>::iterator it = N.begin(); it!=N.end(); it++){ if( (*it)->getType() == RESOURCE_TYPE && hungry){ target = *it; hasTarget = true; @@ -77,14 +96,18 @@ void Creature::setTarget() if(!hasTarget&&!wander){ wander = true; - SDL_Rect r = {rand() % WINDOW_X, rand() % WINDOW_Y, 0, 0}; - wTarget = r; + float x = -30.0 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30-(-30)))); + float y = -30.0 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30-(-30)))); + Location tmp; + tmp.x = x; + tmp.y = y; + wTarget = tmp; } } void Creature::checkTarget() { - for(std::vector <Entity*>::iterator it = N.begin(); it!=N.end(); it++) + for(std::list <Entity*>::iterator it = N.begin(); it!=N.end(); it++) if( target == *it ) return; @@ -95,64 +118,64 @@ void Creature::checkTarget() void Creature::Action() { if(hasTarget){ - if( Distance(rect,target->getRect()) < mine.reach && target->getType() == RESOURCE_TYPE){ + if( Distance(L,target->getLocation()) < mine.reach && target->getType() == RESOURCE_TYPE){ target->eat(mine.bite); health+=mine.bite; amountAte++; - if(rect.w <= mine.sizeMax && mine.amountToGrow <= amountAte){ - amountAte = 0; - rect.w = rect.h = rect.w + 1; - } + //if(L.w <= mine.sizeMax && mine.amountToGrow <= amountAte){ + // amountAte = 0; + // L.w = L.h = L.w + 1; + //} if(target->getAmount()<=0) hasTarget = false; } - else if( Distance(rect,target->getRect()) < mine.reach && target->getType() == CREATURE_TYPE && target->getGender() != gender ){ + else if( Distance(L,target->getLocation()) < mine.reach && target->getType() == CREATURE_TYPE && target->getGender() != gender ){ target->impregnate(mine); hasTarget = false; } else - moveTowards(target->getRect()); + moveTowards(target->getLocation()); } else if(wander){ - if(Distance(rect,wTarget) < mine.reach) + if(Distance(L,wTarget) < mine.reach) wander = false; else moveTowards(wTarget); } } -void Creature::moveTowards(SDL_Rect R) +void Creature::moveTowards(Location t) { - if( rect.x == R.x ){ - if( rect.y < R.y ) - rect.y+=mine.speed; + if( L.x == t.x ){ + if( L.y < t.y ) + L.y+=mine.speed; else - rect.y-=mine.speed; + L.y-=mine.speed; } - else if( rect.y == R.y ){ - if( rect.x < R.x ) - rect.x+=mine.speed; + else if( L.y == t.y ){ + if( L.x < t.x ) + L.x+=mine.speed; else - rect.x-=mine.speed; + L.x-=mine.speed; } - else if( rect.x < R.x ){ - if( rect.y < R.y ){ - rect.x+=mine.speed; - rect.y+=mine.speed; + else if( L.x < t.x ){ + if( L.y < t.y ){ + L.x+=mine.speed; + L.y+=mine.speed; } else{ - rect.x+=mine.speed; - rect.y-=mine.speed; + L.x+=mine.speed; + L.y-=mine.speed; } } - else if ( rect.x > R.x ){ - if( rect.y < R.y ){ - rect.x-=mine.speed; - rect.y+=mine.speed; + else if ( L.x > t.x ){ + if( L.y < t.y ){ + L.x-=mine.speed; + L.y+=mine.speed; } else{ - rect.x-=mine.speed; - rect.y-=mine.speed; + L.x-=mine.speed; + L.y-=mine.speed; } } } diff --git a/src/entity.cpp b/src/entity.cpp index a2c2d87..13bd290 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -2,19 +2,6 @@ void Entity::Place() { - if(type == CREATURE_TYPE){ - if(gender) - SDL_SetRenderDrawColor(renderer,255,0,0,255); - else - if(pregnate) - SDL_SetRenderDrawColor(renderer,255,0,255,255); - else - SDL_SetRenderDrawColor(renderer,0,0,255,255); - } - else if (type == RESOURCE_TYPE) - SDL_SetRenderDrawColor(renderer,0,255,0,255); - - SDL_RenderFillRect(renderer, &rect); - - SDL_SetRenderDrawColor(renderer,0,0,0,0); + gfxData.x = L.x; + gfxData.y = L.y; } diff --git a/src/geoshader.cpp b/src/geoshader.cpp new file mode 100644 index 0000000..b870313 --- /dev/null +++ b/src/geoshader.cpp @@ -0,0 +1,115 @@ +#include "geoshader.hpp" +#include <iostream> +#include <fstream> + +GeoShader::GeoShader(const std::string& fileName) +{ + m_program = glCreateProgram(); + + /* load shader from static vars + m_shaders[0] = CreateShader(GL_VERTEX_SHADER, vertexShaderSrc); + m_shaders[1] = CreateShader(GL_FRAGMENT_SHADER, fragmentShaderSrc); + m_shaders[2] = CreateShader(GL_GEOMETRY_SHADER, geometryShaderSrc); + */ + + m_shaders[0] = CreateShader(LoadShader(fileName + ".vert"), GL_VERTEX_SHADER); + m_shaders[1] = CreateShader(LoadShader(fileName + ".frag"), GL_FRAGMENT_SHADER); + m_shaders[2] = CreateShader(LoadShader(fileName + ".geom"), GL_GEOMETRY_SHADER); + + + for(unsigned int i=0; i < NUM_SHADERS; i++) + glAttachShader(m_program, m_shaders[i]); + + glLinkProgram(m_program); + CheckShaderError(m_program, GL_LINK_STATUS, true, "error shader failed to link: "); + + glValidateProgram(m_program); + CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "error shader is invalid: "); + + glUseProgram(m_program); +} + +GeoShader::~GeoShader() +{ + for(unsigned int i=0; i< NUM_SHADERS; i++){ + glDetachShader(m_program, m_shaders[i]); + glDeleteShader(m_shaders[i]); + } +} + +void GeoShader::Bind() +{ + glUseProgram(m_program); +} + + +void GeoShader::Update(const Transform& transform, const Camera& camera) +{ + glm::mat4 MVP = transform.GetMVP(camera); + glm::mat4 Normal = transform.GetModel(); + + glUniformMatrix4fv(m_uniforms[0], 1, GL_FALSE, &MVP[0][0]); +} + +GLuint GeoShader::CreateShader(const std::string& text, GLenum shaderType) +{ + GLuint shader = glCreateShader(shaderType); + if(shader == 0) + std::cerr << "Error: Shader Creation Failed" << std::endl; + + const GLchar* shaderSource[1]; + GLint shaderSourceLengths[1]; + + shaderSource[0] = text.c_str(); + shaderSourceLengths[0] = text.length(); + + glShaderSource(shader, 1, shaderSource, shaderSourceLengths); + glCompileShader(shader); + + CheckShaderError(shader, GL_COMPILE_STATUS, false, "error shader compilation failed to link: "); + + return shader; +} + + +void GeoShader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage) +{ + GLint success = 0; + GLchar error[1024] = { 0 }; + + if(isProgram) + glGetProgramiv(shader, flag, &success); + else + glGetShaderiv(shader, flag, &success); + + if(success == GL_FALSE) + { + if(isProgram) + glGetProgramInfoLog(shader, sizeof(error), NULL, error); + else + glGetShaderInfoLog(shader, sizeof(error), NULL, error); + + std::cerr << errorMessage << ": '" << error << "'" << std::endl; + } +} + +std::string GeoShader::LoadShader(const std::string& fileName) +{ + std::ifstream file; + file.open((fileName).c_str()); + + std::string output; + std::string line; + + if(file.is_open()){ + while(file.good()){ + getline(file, line); + output.append(line + "\n"); + } + } + else{ + std::cerr << "Unable to load shader: " << fileName << std::endl; + } + + return output; +} diff --git a/src/list.cpp b/src/list.cpp index afe51a3..fab5813 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -1,30 +1,33 @@ #include "list.hpp" -List::List(Window m) +List::List() { - main = m; + int i; + Dna defaultDNA; + //SDL_Rect rect = {0,0,defaultDNA.sizeMax/5,defaultDNA.sizeMax/5}; + Location tmp; + tmp.x = tmp.y = 0; + for(i=0;i<CREATURES;i++){ + Creature X(tmp,defaultDNA); + C.push_back(X); + } - int i; - Dna defaultDNA; - SDL_Rect Rect = {0,0,defaultDNA.sizeMax/5,defaultDNA.sizeMax/5}; - for(i=0;i<CREATURES;i++){ - Creature X(main,Rect,defaultDNA); - C.push_back(X); - } + //rect = {0,0,RESOURCE_SIZE_START,RESOURCE_SIZE_START}; + for(i=0;i<RESOURCES;i++){ + Resource Y(tmp); + R.push_back(Y); + } - Rect = {0,0,RESOURCE_SIZE_START,RESOURCE_SIZE_START}; - for(i=0;i<RESOURCES;i++){ - Resource Y(main,Rect); - R.push_back(Y); - } + R1 = Rectangle(0,0,60,60); + tree = Quadtree(0,R1); } void List::Remove() { for(std::list<Creature>::iterator it = C.begin(); it!=C.end(); it++) if(it->getHealth()<=0){ - SDL_Rect Rect = it->getRect(); - Resource r = Resource(main,Rect); + Location tmp = it->getLocation(); + Resource r = Resource(tmp); R.push_back(r); C.erase(it--); } @@ -37,15 +40,14 @@ void List::Remove() void List::Behavior() { for(std::list<Creature>::iterator it = C.begin(); it!=C.end(); it++){ - std::vector<Entity*> N = getNear(*it); + std::list<Entity*> N = getNear(*it); it->giveN(N); it->Behavior(); if(it->getPregnancyReady()){ Dna D = it->getChildDNA(); - SDL_Rect rect = it->getRect(); - rect.h = rect.w = D.sizeMax / 5; - Creature X(main,rect,D); + Location tmp = it->getLocation(); + Creature X(tmp,D); C.push_back(X); it->hadPregnancy(); } @@ -57,34 +59,38 @@ void List::Behavior() void List::Place() { - SDL_Rect rect = {0,0,RESOURCE_SIZE_START,RESOURCE_SIZE_START}; + tree.clear(); + + Location tmp; + tmp.x = tmp.y = 0; while(R.size() < MINIMUM_RESOURCES){ - Resource Y(main,rect); + Resource Y(tmp); R.push_back(Y); } - for(std::list<Creature>::iterator it = C.begin(); it!=C.end(); it++) + for(std::list<Creature>::iterator it = C.begin(); it!=C.end(); it++){ it->Place(); + tree.insert(&(*it));; + } - for(std::list<Resource>::iterator it = R.begin(); it!=R.end(); it++) + for(std::list<Resource>::iterator it = R.begin(); it!=R.end(); it++){ it->Place(); + tree.insert(&(*it));; + } } -std::vector<Entity*> List::getNear(Creature nC) +std::list<Entity*> List::getNear(Creature nC) { - std::vector<Entity*> N; - - for(std::list<Resource>::iterator it = R.begin(); it!=R.end(); it++) - if(nC.getBestSense() > Distance(nC.getRect(),it->getRect())) - N.push_back(&(*it)); - - for(std::list<Creature>::iterator it = C.begin(); it!=C.end(); it++) - if(&nC == &(*it)) - continue; - else if(nC.getBestSense() > Distance(nC.getRect(),it->getRect())) - N.push_back(&(*it)); + std::list<Entity*> N; + N.clear(); + N = tree.retrieve(N, nC.getGFXD()); + //std::vector<Entity*> x{std::begin(N),std::begin(N)}; return N; } +std::vector<GraphicsData> List::drawQuadTree(){ + return tree.Draw(); +} + diff --git a/src/main.cpp b/src/main.cpp index 5170bf3..e385f9f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,16 +3,36 @@ int main()
{
srand(time(NULL));
- Window main;
- List L(main);
- Event e;
- Timer fps;
- int speed = 60;
- bool pause = false;
+ Window main(WINDOW_X, WINDOW_Y, "natures");
+ List L;
+ Event e;
+
+ //New opengl stuff
+ Transform transform;
+ Camera camera(glm::vec3(0,0,70), 70.0f, (float)800/(float)600, 0.01f, 1000.0f);
+ GeoShader shader("./inc/opengl/theshader");
+ GeoShader shader2("./inc/opengl/basicshader");
+ Rectdrawer rectrenderer(shader2);
+ SpriteBatch _spriteBatch(shader);
+
+ _spriteBatch.init();
+ shader.Bind();
+
+ int uniModel = glGetUniformLocation(shader.m_program, "MVP");
+ glUniformMatrix4fv(uniModel, 1, false, &transform.GetMVP(camera)[0][0]);
+ shader2.Bind();
+
+ int uniModel2 = glGetUniformLocation(shader2.m_program, "MPV");
+ glUniformMatrix4fv(uniModel2, 1, false, &transform.GetMVP(camera)[0][0]);
+ int countedFrames = 0;
+
+ Timer fps;
+ int speed = 60;
+ bool pause = false;
while(e.gRun()){
- fps.Start();
+ //fps.Start();
while(e.Poll()){
if(e.gEventType() == SDL_QUIT)
e.off();
@@ -26,19 +46,34 @@ int main() }
if(!pause){
- main.Clear();
+ main.Clear(0.0f,0.0f,0.0f,1.0f);
L.Remove();
L.Behavior();
L.Place();
- main.Render();
+ shader.Bind();
+ _spriteBatch.begin();
+ for(std::list<Creature>::iterator it = L.C.begin(); it != L.C.end(); it++)
+ _spriteBatch.draw(it->gfxData);;
+
+ for(std::list<Resource>::iterator it = L.R.begin(); it != L.R.end(); it++)
+ _spriteBatch.draw(it->gfxData);;
+
+ _spriteBatch.end();
+ _spriteBatch.renderBatch();
+
+ main.swapBuffers();
}
- if(fps.getTicks() < (1000 / speed))
- SDL_Delay((1000 / speed) - fps.getTicks());
+ float avgFPS = countedFrames / ( fps.getTicks() / 1000.f );
+ if( avgFPS > 200000 ){
+ avgFPS = 0;
+ }
+ ++countedFrames;
+ //if(fps.getTicks() < (1000 / speed))
+ // SDL_Delay((1000 / speed) - fps.getTicks());
}
- main.Destroy();
return 0;
}
diff --git a/src/quadtree.cpp b/src/quadtree.cpp new file mode 100644 index 0000000..e347e55 --- /dev/null +++ b/src/quadtree.cpp @@ -0,0 +1,140 @@ +#include "quadtree.hpp"
+
+
+Quadtree::Quadtree(){}
+
+Quadtree::Quadtree(int pLevel, Rectangle pBounds){
+ level = pLevel;
+ bounds = pBounds;
+ isNull=false;
+ nodes = new Quadtree[4];
+ gfxDataRect.x = pBounds.x * 1.01;
+ gfxDataRect.y = pBounds.y * 1.05;
+ gfxDataRect.r = 255;
+ gfxDataRect.g = 0;
+ gfxDataRect.b = 255;
+ gfxDataRect.sides = pBounds.height;
+}
+
+void Quadtree::clear(){
+ objects.clear();
+
+ for (int i = 0; i < 4; i++)
+ if (!nodes[i].isNull) {
+ nodes[i].objects.clear();
+ nodes[i].clear();
+ }
+
+ delete[] nodes;
+ if(level == 0)
+ nodes = new Quadtree[4];
+ }
+
+ void Quadtree::split(){
+ float subWidth = (bounds.getWidth() / 2);
+ float subHeight = (bounds.getHeight() / 2);
+ float x = bounds.getX();
+ float y = bounds.getY();
+
+
+ Rectangle R0(x + subWidth/2, y + subHeight/2, subWidth, subHeight);
+ Rectangle R1(x - subWidth/2, y + subHeight/2, subWidth, subHeight);
+ Rectangle R2(x - subWidth/2, y - subHeight/2, subWidth, subHeight);
+ Rectangle R3(x + subWidth/2, y - subHeight/2, subWidth, subHeight);
+
+ Quadtree Q0(level+1, R0);
+ Quadtree Q1(level+1, R1);
+ Quadtree Q2(level+1, R2);
+ Quadtree Q3(level+1, R3);
+
+ nodes[0] = Q0;
+ nodes[1] = Q1;
+ nodes[2] = Q2;
+ nodes[3] = Q3;
+}
+
+
+int Quadtree::getIndex(GraphicsData object) {
+ int index = -1;
+
+ bool topQuadrant = (object.getY() > bounds.getY());
+ bool bottomQuadrant = (object.getY() < bounds.getY());
+
+ if (object.getX() < bounds.getX()) {
+ if (topQuadrant)
+ index = 1;
+ else if (bottomQuadrant)
+ index = 2;
+ }
+ else if (object.getX() > bounds.getX()) {
+ if (topQuadrant)
+ index = 0;
+ else if (bottomQuadrant)
+ index = 3;
+ }
+
+ return index;
+}
+
+void Quadtree::insert(Entity* iter){
+ if (!nodes[0].isNull) {
+ int index = getIndex((*iter).getGFXD());
+ if (index != -1) {
+ nodes[index].insert(iter);
+ return;
+ }
+ }
+
+ objects.emplace_back(iter);
+
+ if (objects.size() > MAX_OBJECTS && level < MAX_LEVELS) {
+ if (nodes[0].isNull)
+ split();
+
+
+ for(std::list <Entity*>::iterator it = objects.begin(); it!=objects.end();it++){
+ int index = getIndex((*it)->getGFXD());
+ if (index != -1) {
+ nodes[index].insert(*it);
+ objects.erase(it--);
+ }
+ }
+ }
+}
+
+
+std::vector<GraphicsData> Quadtree::Draw(){
+ std::vector<GraphicsData> retdat;
+
+ for (int i = 0; i < 4; i++) {
+ if (!nodes[i].isNull) {
+ std::vector<GraphicsData> temp = nodes[i].Draw();
+ retdat.insert(retdat.end(), temp.begin(), temp.end());
+ }
+ }
+
+ if (!nodes[0].isNull)
+ retdat.emplace_back(nodes[0].gfxDataRect);
+ if (!nodes[1].isNull)
+ retdat.emplace_back(nodes[1].gfxDataRect);
+ if (!nodes[2].isNull)
+ retdat.emplace_back(nodes[2].gfxDataRect);
+ if (!nodes[3].isNull)
+ retdat.emplace_back(nodes[3].gfxDataRect);
+
+ retdat.emplace_back(gfxDataRect);
+
+ return retdat;
+}
+
+std::list<Entity*> Quadtree::retrieve(std::list<Entity*> returnObjects, GraphicsData obj) {
+ int index = getIndex(obj);
+ if (index != -1 && !nodes[0].isNull) {
+ returnObjects = nodes[index].retrieve(returnObjects, obj);
+ }
+ for(std::list <Entity*>::iterator it = objects.begin(); it!=objects.end(); it++){
+ returnObjects.emplace_back(*it);
+ }
+
+ return returnObjects;
+}
diff --git a/src/rectdrawer.cpp b/src/rectdrawer.cpp new file mode 100644 index 0000000..980f348 --- /dev/null +++ b/src/rectdrawer.cpp @@ -0,0 +1,135 @@ +#include "rectdrawer.hpp"
+
+Rectdrawer::Rectdrawer(GeoShader theshader) : _vbo(0), _vao(0), shader(theshader){
+ // Generate the VAO if it isn't already generated
+ if (_vao == 0) {
+ glGenVertexArrays(1, &_vao);
+ }
+
+ // Bind the VAO. All subsequent opengl calls will modify it's state.
+ glBindVertexArray(_vao);
+
+ //G enerate the VBO if it isn't already generated
+ if (_vbo == 0) {
+ glGenBuffers(1, &_vbo);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+
+ //Tell opengl what attribute arrays we need
+ GLint posAttrib = glGetAttribLocation(shader.m_program, "pos");
+ glEnableVertexAttribArray(posAttrib);
+
+ GLint colAttrib = glGetAttribLocation(shader.m_program, "color");
+ glEnableVertexAttribArray(colAttrib);
+
+ GLint sidesAttrib = glGetAttribLocation(shader.m_program, "sides");
+ glEnableVertexAttribArray(sidesAttrib);
+
+ // glEnableVertexAttribArray(2);
+
+ //This is the position attribute pointer
+ glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), 0); //This is the color attribute pointer
+ glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), (void*) (2 * sizeof(float))); //This is the UV attribute pointer
+ glVertexAttribPointer(sidesAttrib, 1, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), (void*) (5 * sizeof(float)));
+ glBindVertexArray(0);
+
+
+}
+
+Rectdrawer::~Rectdrawer()
+{
+}
+
+void Rectdrawer::draw(const GraphicsData& gfxData) {
+ _gfx.emplace_back(gfxData);
+}
+
+
+
+void Rectdrawer::begin() {
+ _renderBatches.clear();
+ _gfx.clear();
+}
+
+void Rectdrawer::end() {
+ // Set up all pointers for fast sorting
+ _gfxPtr.resize(_gfx.size());
+ for (int i = 0; i < _gfx.size(); i++) {
+ _gfxPtr[i] = &_gfx[i];
+ }
+
+ //sortGlyphs();
+ createRenderBatches();
+}
+
+void Rectdrawer::renderBatch() {
+
+ // Bind our VAO. This sets up the opengl state we need, including the
+ // vertex attribute pointers and it binds the VBO
+ glBindVertexArray(_vao);
+
+ for (int i = 0; i < _renderBatches.size(); i++) {
+ glDrawArrays(GL_POINTS, _renderBatches[i].offset, _renderBatches[i].numVertices);
+ }
+ glBindVertexArray(0);
+}
+
+
+// needs edit here for rectangle instead of other geometry
+void Rectdrawer::createRenderBatches() {
+ // This will store all the vertices that we need to upload
+ std::vector <float> vertices;
+ // Resize the buffer to the exact size we need so we can treat
+ // it like an array
+ vertices.resize(_gfxPtr.size() * 6);
+
+ if (_gfxPtr.empty()) {
+ return;
+ }
+
+ int offset = 0; // current offset
+ int cv = 0; // current vertex
+
+ //Add the first batch
+ _renderBatches.emplace_back(offset, 6);
+ vertices[cv++] = _gfxPtr[0]->x;
+ vertices[cv++] = _gfxPtr[0]->y;
+ vertices[cv++] = _gfxPtr[0]->r;
+ vertices[cv++] = _gfxPtr[0]->g;
+ vertices[cv++] = _gfxPtr[0]->b;
+ vertices[cv++] = _gfxPtr[0]->sides;
+
+ offset += 6;
+
+ //Add all the rest of the glyphs
+ //std::cout << "ptr size = " << _gfxPtr.size() << std::endl;
+ for (int cg = 1; cg < _gfxPtr.size(); cg++) {
+
+ _renderBatches.back().numVertices += 6;
+
+ vertices[cv++] = _gfxPtr[cg]->x;
+ vertices[cv++] = _gfxPtr[cg]->y;
+ vertices[cv++] = _gfxPtr[cg]->r;
+ vertices[cv++] = _gfxPtr[cg]->g;
+ vertices[cv++] = _gfxPtr[cg]->b;
+ vertices[cv++] = _gfxPtr[cg]->sides;
+
+ offset += 6;
+ }
+
+
+
+ // Bind our VBO
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+ // Orphan the buffer (for speed)
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
+ // Upload the data
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float), vertices.data());
+
+ // Unbind the VBO
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+}
diff --git a/src/resource.cpp b/src/resource.cpp index ee9100a..31811ca 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1,15 +1,21 @@ #include "resource.hpp" -Resource::Resource(Window M, SDL_Rect R) +Resource::Resource(Location t) { - renderer = M.getRenderer(); - rect = R; + L = t; - if(rect.x == 0 && rect.y == 0){ - rect.x = rand()%WINDOW_X; - rect.y = rand()%WINDOW_Y; + if(L.x == 0 && L.y == 0){ + L.x = -30 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30.0-(-30.0)))); + L.y = -30 + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/(30.0-(-30.0)))); } + gfxData.x = L.x; + gfxData.y = L.y; + gfxData.r = 0.0; + gfxData.g = 1.0; + gfxData.b = 0.0; + gfxData.sides = 10.0; + type = RESOURCE_TYPE; amount = RESOURCE_AMOUNT_START; growAmount = RESOURCE_GROW; @@ -24,6 +30,6 @@ void Resource::grow() { if(amount < RESOURCE_AMOUNT_MAX){ amount+=growAmount; - rect.h = rect.w = map(amount,0,RESOURCE_AMOUNT_MAX,0,RESOURCE_SIZE_MAX); + L.h = L.w = map(amount,0,RESOURCE_AMOUNT_MAX,0,RESOURCE_SIZE_MAX); } } diff --git a/src/spritebatch.cpp b/src/spritebatch.cpp new file mode 100644 index 0000000..91e04ba --- /dev/null +++ b/src/spritebatch.cpp @@ -0,0 +1,185 @@ +#include "spritebatch.hpp"
+
+SpriteBatch::SpriteBatch(GeoShader theshader) : _vbo(0), _vao(0), shader(theshader)
+{
+ //shader = theshader;
+}
+
+SpriteBatch::~SpriteBatch()
+{
+
+}
+
+void SpriteBatch::init()
+{
+ createVertexArray();
+}
+
+
+void SpriteBatch::begin() {
+ //_sortType = sortType;
+ _renderBatches.clear();
+
+ // Makes _glpyhs.size() == 0, however it does not free internal memory.
+ // So when we later call emplace_back it doesn't need to internally call new.
+ _gfx.clear();
+}
+
+void SpriteBatch::end() {
+ // Set up all pointers for fast sorting
+ _gfxPtr.resize(_gfx.size());
+ for (int i = 0; i < _gfx.size(); i++) {
+ _gfxPtr[i] = &_gfx[i];
+ }
+
+ //sortGlyphs();
+ createRenderBatches();
+}
+
+void SpriteBatch::draw(const GraphicsData& gfxData) {
+ _gfx.emplace_back(gfxData);
+}
+
+void SpriteBatch::renderBatch() {
+
+ // Bind our VAO. This sets up the opengl state we need, including the
+ // vertex attribute pointers and it binds the VBO
+ glBindVertexArray(_vao);
+
+ for (int i = 0; i < _renderBatches.size(); i++) {
+ //glBindTexture(GL_TEXTURE_2D, _renderBatches[i].texture);
+
+ glDrawArrays(GL_POINTS, _renderBatches[i].offset, _renderBatches[i].numVertices);
+ }
+ glBindVertexArray(0);
+}
+
+void SpriteBatch::createRenderBatches() {
+ // This will store all the vertices that we need to upload
+ std::vector <float> vertices;
+ // Resize the buffer to the exact size we need so we can treat
+ // it like an array
+ vertices.resize(_gfxPtr.size() * 6);
+
+ if (_gfxPtr.empty()) {
+ return;
+ }
+
+ int offset = 0; // current offset
+ int cv = 0; // current vertex
+
+ //Add the first batch
+ _renderBatches.emplace_back(offset, 6);
+ vertices[cv++] = _gfxPtr[0]->x;
+ vertices[cv++] = _gfxPtr[0]->y;
+ vertices[cv++] = _gfxPtr[0]->r;
+ vertices[cv++] = _gfxPtr[0]->g;
+ vertices[cv++] = _gfxPtr[0]->b;
+ vertices[cv++] = _gfxPtr[0]->sides;
+
+ offset += 6;
+
+ //Add all the rest of the glyphs
+ //std::cout << "ptr size = " << _gfxPtr.size() << std::endl;
+ for (int cg = 1; cg < _gfxPtr.size(); cg++) {
+
+ // Check if this glyph can be part of the current batch
+ //if (_gfxPtr[cg]->texture != _gfxPtr[cg - 1]->texture) {
+ // Make a new batch
+ // _renderBatches.emplace_back(offset, 6);
+ //} else {
+ // If its part of the current batch, just increase numVertices
+ _renderBatches.back().numVertices += 6;
+ //}
+ vertices[cv++] = _gfxPtr[cg]->x;
+ vertices[cv++] = _gfxPtr[cg]->y;
+ vertices[cv++] = _gfxPtr[cg]->r;
+ vertices[cv++] = _gfxPtr[cg]->g;
+ vertices[cv++] = _gfxPtr[cg]->b;
+ vertices[cv++] = _gfxPtr[cg]->sides;
+
+ offset += 6;
+ }
+
+
+
+ // Bind our VBO
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+ // Orphan the buffer (for speed)
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
+ // Upload the data
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float), vertices.data());
+
+ // Unbind the VBO
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+}
+
+void SpriteBatch::createVertexArray() {
+
+ // Generate the VAO if it isn't already generated
+ if (_vao == 0) {
+ glGenVertexArrays(1, &_vao);
+ }
+
+ // Bind the VAO. All subsequent opengl calls will modify it's state.
+ glBindVertexArray(_vao);
+
+ //G enerate the VBO if it isn't already generated
+ if (_vbo == 0) {
+ glGenBuffers(1, &_vbo);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+
+ //Tell opengl what attribute arrays we need
+ GLint posAttrib = glGetAttribLocation(shader.m_program, "pos");
+ glEnableVertexAttribArray(posAttrib);
+
+ GLint colAttrib = glGetAttribLocation(shader.m_program, "color");
+ glEnableVertexAttribArray(colAttrib);
+
+ GLint sidesAttrib = glGetAttribLocation(shader.m_program, "sides");
+ glEnableVertexAttribArray(sidesAttrib);
+
+ // glEnableVertexAttribArray(2);
+
+ //This is the position attribute pointer
+ glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), 0); //This is the color attribute pointer
+ glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), (void*) (2 * sizeof(float))); //This is the UV attribute pointer
+ glVertexAttribPointer(sidesAttrib, 1, GL_FLOAT, GL_FALSE,
+ 6 * sizeof(float), (void*) (5 * sizeof(float)));
+ glBindVertexArray(0);
+
+}
+
+/*
+void SpriteBatch::sortGlyphs() {
+
+ switch (_sortType) {
+ case GlyphSortType::BACK_TO_FRONT:
+ std::stable_sort(_glyphPointers.begin(), _glyphPointers.end(), compareBackToFront);
+ break;
+ case GlyphSortType::FRONT_TO_BACK:
+ std::stable_sort(_glyphPointers.begin(), _glyphPointers.end(), compareFrontToBack);
+ break;
+ case GlyphSortType::TEXTURE:
+ std::stable_sort(_glyphPointers.begin(), _glyphPointers.end(), compareTexture);
+ break;
+ }
+}
+bool SpriteBatch::compareFrontToBack(Glyph* a, Glyph* b) {
+ return (a->depth < b->depth);
+}
+
+bool SpriteBatch::compareBackToFront(Glyph* a, Glyph* b) {
+ return (a->depth > b->depth);
+}
+
+bool SpriteBatch::compareTexture(Glyph* a, Glyph* b) {
+ return (a->texture < b->texture);
+}
+
+}
+*/
diff --git a/src/window.cpp b/src/window.cpp index f7868a4..28af6bf 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,31 +1,41 @@ #include "window.hpp" -Window::Window() +Window::Window(int width, int height, const std::string& title) { - SDL_Init(SDL_INIT_VIDEO); - main = SDL_CreateWindow("main",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,WINDOW_X,WINDOW_Y,SDL_WINDOW_SHOWN); - renderer = SDL_CreateRenderer(main,-1,SDL_RENDERER_ACCELERATED); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_Init(SDL_INIT_EVERYTHING); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + main = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,SDL_WINDOW_OPENGL); + glContext = SDL_GL_CreateContext(main); + GLenum status = glewInit(); + closed = false; + + if(status != GLEW_OK) + std::cerr << "Failiure to init." << std::endl; + } -void Window::Destroy() +Window::~Window() { - SDL_DestroyRenderer(renderer); + SDL_GL_DeleteContext(glContext); SDL_DestroyWindow(main); SDL_Quit(); } -void Window::Clear() +void Window::swapBuffers() { - SDL_RenderClear(renderer); + SDL_GL_SwapWindow(main); } -void Window::Render() +void Window::Clear(float r, float g, float b, float a) { - SDL_RenderPresent(renderer); + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); } -SDL_Renderer* Window::getRenderer() -{ - return renderer; -} |