summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriamn1ck <iamn1ck@yahoo.com>2017-02-19 07:00:34 -0600
committerTom Barrett <tombarrett@siu.edu>2017-03-07 13:22:46 -0600
commit74c6854fd8dcbaee736ac0421805ff1e03c4a1e2 (patch)
tree4a3ae40bea9b07a2111128e98d9272bdbac2af87 /src
parent03885192b9ff7d3c5e2dcfd98aefd21e9b62f603 (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.cpp103
-rw-r--r--src/entity.cpp17
-rw-r--r--src/geoshader.cpp115
-rw-r--r--src/list.cpp78
-rw-r--r--src/main.cpp59
-rw-r--r--src/quadtree.cpp140
-rw-r--r--src/rectdrawer.cpp135
-rw-r--r--src/resource.cpp20
-rw-r--r--src/spritebatch.cpp185
-rw-r--r--src/window.cpp40
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;
-}