]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
MODERN
authordrumsetmonkey <abelleisle@roadrunner.com>
Fri, 6 May 2016 11:59:33 +0000 (07:59 -0400)
committerdrumsetmonkey <abelleisle@roadrunner.com>
Fri, 6 May 2016 11:59:33 +0000 (07:59 -0400)
include/common.hpp
include/entities.hpp
include/ui_menu.hpp
main.cpp
src/entities.cpp
src/ui.cpp
src/world.cpp

index 92318d9eb73306dcb954220ff683e896215c6e48..bbe852fbe260058d17f9130d1ce58d57a97bf184 100644 (file)
@@ -16,6 +16,8 @@
 #include <cmath>
 #include <algorithm>
 
+#include <shader_utils.hpp>
+
 #define GLEW_STATIC
 #include <GL/glew.h>
 
 #include <SDL2/SDL_image.h>
 #include <SDL2/SDL_mixer.h>
 
+#define GLM_FORCE_RADIANS
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtc/noise.hpp>
+
 #include <config.hpp>
 
 #ifdef __WIN32__
@@ -51,6 +59,11 @@ const float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC;
 
 extern GLuint colorIndex;      // Texture.cpp?
 
+/**
+ *     This separates xml strings with
+ */
+std::vector<std::string> StringTokenizer(const std::string& str, char delim);
+
 /**
  * This structure contains a set of coordinates for ease of coding.
  */
@@ -62,30 +75,62 @@ typedef struct {
 
 typedef ivec2 dim2;
 
-struct _vec2 {
+class vec2 {
+public:
        float x;
        float y;
 
-       bool operator==(const _vec2 &v) {
+       vec2 ()
+       {
+               x = y = 0.0f;
+       }
+
+       vec2 (float _x, float _y)
+       {
+               x = _x;
+               y = _y;
+       }
+
+       bool operator==(const vec2 &v) {
                return (x == v.x) && (y == v.y);
        }
        template<typename T>
-       const _vec2 operator=(const T &n) {
+       const vec2 operator=(const T &n) {
                x = y = n;
                return *this;
        }
        template<typename T>
-       const _vec2 operator+(const T &n) {
-               return _vec2 {x + n, y + n};
+       const vec2 operator+(const T &n) {
+               return vec2 (x + n, y + n);
        }
 };
-typedef struct _vec2 vec2;
 
-typedef struct {
+class vec3{
+public:
        float x;
        float y;
        float z;
-} vec3;
+
+       vec3 ()
+       {
+               x = y = z = 0.0f;
+       }
+
+       vec3 (float _x, float _y, float _z)
+       {
+               x = _x;
+               y = _y;
+               z = _z;
+       }
+
+       vec3 (float _x, float _y)
+       {
+               x = _x;
+               y = _y;
+               z = 1.0f;
+       }
+
+};
 
 /**
  * This structure contains two sets of coordinates for ray drawing.
@@ -96,26 +141,35 @@ typedef struct {
        vec2 end;
 } Ray;
 
-struct _color {
+class Color{
+public:
        float red;
        float green;
        float blue;
-       _color operator-=(float a) {
+       Color()
+       {
+               red = green = blue = 0;
+       }
+       Color(float r, float g ,float b)
+       {
+               red = r;
+               green = g;
+               blue = b;
+       }
+       Color operator-=(float a) {
                red-=a;
                green-=a;
                blue-=a;
                return{red+a,green+a,blue+a};
        }
-       _color operator+=(float a) {
+       Color operator+=(float a) {
                return{red+a,green+a,blue+a};
        }
-       _color operator=(float a) {
+       Color operator=(float a) {
                return{red=a,green=a,blue=a};
        }
 };
 
-typedef struct _color Color;
-
 // gets the length of `n` HLINEs
 template<typename T>
 inline T HLINES(const T &n)
@@ -138,8 +192,15 @@ extern vec2 offset;
 // the shader program created in main.cpp
 extern GLuint shaderProgram;
 
-// splits a string into tokens
-std::vector<std::string> StringTokenizer(const std::string& str, char delim);
+extern GLuint textShader;
+extern GLint textShader_attribute_coord;
+extern GLint textShader_attribute_tex;
+extern GLint textShader_uniform_texture;
+
+extern GLuint worldShader;
+extern GLint worldShader_attribute_coord;
+extern GLint worldShader_attribute_tex;
+extern GLint worldShader_uniform_texture;
 
 /**
  *     Prints a formatted debug message to the console, along with the callee's file and line
index 5417dac4bb5d070e1c7bee6b7e35f823f1716085..3e78687dbf453e07a165ff8d1a58cd0e2675637d 100644 (file)
@@ -149,7 +149,7 @@ public:
        ~Particles(void){}
 
        // draws the particle
-       void draw(void) const;
+       std::vector<std::pair<vec2, vec3>> draw(void) const;
 
        // updates a particle
        void update(float _gravity, float ground_y);
@@ -183,6 +183,7 @@ protected:
 public:
        // contains the entity's coordinates, in pixels
        vec2 loc;
+       float z;
 
        // contains the entity's velocity, in pixels
        vec2 vel;
index 1ec7ff3b57c3b35f9c49389a2911a0801432ea18..f7b665e365a62b4ab8948efc58cee55fc31d9bba 100644 (file)
@@ -32,6 +32,7 @@ public:
                        float *var;
                } slider;
        };
+       menuItem(){}
        ~menuItem(){
                //button.text = NULL;
                //slider.text = NULL;
index 960c4e5ded85917e1cd675d513c5cf5d0469c71f..8c3b631f110d540b314dbf96c0cbec29a2da3e49 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -54,6 +54,28 @@ Player *player;
 GLuint fragShader;
 GLuint shaderProgram;
 
+/**
+ * These are the source and index variables for our shader
+ * used to draw text and ui elements
+ */
+
+GLuint textShader;
+GLint textShader_attribute_coord;
+GLint textShader_attribute_tex;
+GLint textShader_uniform_texture;
+GLint textShader_uniform_transform;
+
+/**
+ * These are the source and index variables for the world
+ * shader which is used to draw the world items and shade them
+ */
+
+GLuint worldShader;
+GLint worldShader_attribute_coord;
+GLint worldShader_attribute_tex;
+GLint worldShader_uniform_texture;
+GLint worldShader_uniform_transform;
+
 // keeps a simple palette of colors for single-color draws
 GLuint colorIndex;
 
@@ -191,7 +213,26 @@ int main(int argc, char *argv[]){
 
        delete[] shaderSource;
 
-       glEnable(GL_MULTISAMPLE);
+       /**
+        *      Creating the text shader and its attributes/uniforms
+        */
+       textShader = create_program("shaders/new.vert", "shaders/new.frag");
+       textShader_attribute_coord = get_attrib(textShader, "coord2d");
+       textShader_attribute_tex = get_attrib(textShader, "tex_coord");
+       textShader_uniform_texture = get_uniform(textShader, "sampler");
+       textShader_uniform_transform = get_uniform(textShader, "ortho");
+
+
+       /**
+        *      Creating the world's shader and its attributes/uniforms
+        */
+       worldShader = create_program("shaders/world.vert", "shaders/world.frag");
+       worldShader_attribute_coord = get_attrib(worldShader, "coord2d");
+       worldShader_attribute_tex = get_attrib(worldShader, "tex_coord");
+       worldShader_uniform_texture = get_uniform(worldShader, "sampler");
+       worldShader_uniform_transform = get_uniform(worldShader, "ortho");
+
+       //glEnable(GL_MULTISAMPLE);
 
        // load up some fresh hot brice
        game::briceLoad();
@@ -335,22 +376,35 @@ void render() {
        offset.y = std::max(player->loc.y + player->height / 2, SCREEN_HEIGHT / 2.0f);
 
        // "setup"
-       glMatrixMode(GL_PROJECTION);
-       glPushMatrix();
-       glLoadIdentity();
-       glOrtho(floor(offset.x - SCREEN_WIDTH  / 2), floor(offset.x + SCREEN_WIDTH  / 2),
-               floor(offset.y - SCREEN_HEIGHT / 2), floor(offset.y + SCREEN_HEIGHT / 2),
-                       20, -20);
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
-       glLoadIdentity();
-
-       glPushAttrib(GL_DEPTH_BUFFER_BIT);
-
-       // clear the screen
-       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-       // draw the world
+       glm::mat4 projection = glm::ortho(      static_cast<float>(floor(offset.x-SCREEN_WIDTH/2)),     //left
+                                                                               static_cast<float>(floor(offset.x+SCREEN_WIDTH/2)),     //right
+                                                                               static_cast<float>(floor(offset.y-SCREEN_HEIGHT/2)),    //bottom
+                                                                               static_cast<float>(floor(offset.y+SCREEN_HEIGHT/2)),    //top
+                                                                               10.0f,                                                          //near
+                                                                               -10.0f);                                                        //far
+
+       glm::mat4 view = glm::lookAt(glm::vec3(0,0,10.0f),  //pos
+                                                                glm::vec3(0,0,0.0f), //looking at
+                                                                glm::vec3(0,1.0f,0)); //up vector
+
+       glm::mat4 ortho = projection * view;
+
+       glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+       //glEnable(GL_DEPTH_TEST);
+
+       glUseProgram(textShader);
+       glUniformMatrix4fv(textShader_uniform_transform, 1, GL_FALSE, glm::value_ptr(ortho));
+       glUseProgram(worldShader);
+       glUniformMatrix4fv(worldShader_uniform_transform, 1, GL_FALSE, glm::value_ptr(ortho));
+
+       /**************************
+       **** RENDER STUFF HERE ****
+       **************************/
+
+       /**
+        * Call the world's draw function, drawing the player, the world, the background, and entities. Also
+        * draw the player's inventory if it exists.
+        */
        //player->near = true; // allow player's name to be drawn
        currentWorld->draw(player);
 
@@ -396,21 +450,44 @@ void render() {
        if (currentMenu)
                ui::menu::draw();
 
-       // draw the mouse cursor
-       glColor3ub(255,255,255);
-       glEnable(GL_TEXTURE_2D);
-       glBindTexture(GL_TEXTURE_2D, mouseTex);
-       glBegin(GL_QUADS);
-               glTexCoord2f(0,0);glVertex2i(ui::mouse.x                        ,ui::mouse.y                    );
-               glTexCoord2f(1,0);glVertex2i(ui::mouse.x+HLINES(5)      ,ui::mouse.y                    );
-               glTexCoord2f(1,1);glVertex2i(ui::mouse.x+HLINES(5)      ,ui::mouse.y-HLINES(5)  );
-               glTexCoord2f(0,1);glVertex2i(ui::mouse.x                        ,ui::mouse.y-HLINES(5)  );
-       glEnd();
-       glDisable(GL_TEXTURE_2D);
-
-       // wrap up
-       glPopMatrix();
-       SDL_GL_SwapWindow(window);
+               glUseProgram(textShader);
+               glActiveTexture(GL_TEXTURE0);
+               glBindTexture(GL_TEXTURE_2D, mouseTex);
+               glUniform1i(textShader_uniform_texture, 0);
+
+               glEnableVertexAttribArray(textShader_attribute_tex);
+               glEnableVertexAttribArray(textShader_attribute_coord);
+
+               glDisable(GL_DEPTH_TEST);
+
+               GLfloat mouseCoords[] = {
+                       ui::mouse.x                     ,ui::mouse.y,         1.0, //bottom left
+                       ui::mouse.x+15          ,ui::mouse.y,             1.0, //bottom right
+                       ui::mouse.x+15          ,ui::mouse.y-15,          1.0, //top right
+
+                       ui::mouse.x+15          ,ui::mouse.y-15,          1.0, //top right
+                       ui::mouse.x             ,ui::mouse.y-15,          1.0, //top left
+                       ui::mouse.x                     ,ui::mouse.y,             1.0, //bottom left
+               };
+
+               GLfloat mouseTex[] = {
+                       0.0f, 0.0f, //bottom left
+                       1.0f, 0.0f, //bottom right
+                       1.0f, 1.0f, //top right
+
+                       1.0f, 1.0f, //top right
+                       0.0f, 1.0f, //top left
+                       0.0f, 0.0f, //bottom left
+               };
+
+               glVertexAttribPointer(textShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, mouseCoords);
+               glVertexAttribPointer(textShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, mouseTex);
+               glDrawArrays(GL_TRIANGLES, 0, 6);
+
+               glDisableVertexAttribArray(textShader_attribute_coord);
+               glDisableVertexAttribArray(textShader_attribute_tex);
+
+               SDL_GL_SwapWindow(window);
 }
 
 void logic(){
index 5198c014355922340442731d598a3e1654c1b64b..c4e418681e2ca060a12e7f5ce38ad2bc98497cb6 100644 (file)
@@ -88,6 +88,7 @@ void Entity::spawn(float x, float y)
        //canMove       = true;
        ground  = false;
        forcedMove = false;
+       z = 1.0f;
 
        ticksToUse = 0;
        hitCooldown = 0;
@@ -261,6 +262,8 @@ Structures::Structures() { //sets the structure type
 
        //inv = NULL;
        canMove = false;
+
+       z = 1.0f;
 }
 Structures::~Structures() {
        if (name)
@@ -321,8 +324,32 @@ void NPC::drawThingy(void) const
 
 void Entity::draw(void)
 {
-       glPushMatrix();
-       glColor3ub(255,255,255);
+       GLfloat tex_coord[] = {0.0, 0.0,
+                                                  1.0, 0.0,
+                                                  1.0, 1.0,
+
+                                                  1.0, 1.0,
+                                                  0.0, 1.0,
+                                                  0.0, 0.0};
+
+       GLfloat tex_coordL[] = {1.0, 0.0,
+                                                       0.0, 0.0,
+                                                       0.0, 1.0,
+
+                                                       0.0, 1.0,
+                                                       1.0, 1.0,
+                                                       1.0, 0.0};
+
+       GLfloat coords[] = {loc.x, loc.y, z,
+                                               loc.x + width, loc.y, z,
+                                               loc.x + width, loc.y + height, z,
+
+                                               loc.x + width, loc.y + height, z,
+                                               loc.x, loc.y + height, z,
+                                               loc.x, loc.y, z};
+
+
+       glActiveTexture(GL_TEXTURE0);
 
        if (!alive)
                return;
@@ -341,13 +368,6 @@ void Entity::draw(void)
                Mobp(this)->rider->vel.y = .12;
            }
        }
-       if (left) {
-               glScalef(-1.0f,1.0f,1.0f);
-               glTranslatef(0-width-loc.x*2,0,0);
-       }
-       glMatrixMode(GL_TEXTURE);
-       glLoadIdentity();
-       glEnable(GL_TEXTURE_2D);
        switch(type) {
        case PLAYERT:
                static int texState = 0;
@@ -379,30 +399,84 @@ void Entity::draw(void)
                break;
        }
 
-       if (hitCooldown)
+       //TODO
+       /*if (hitCooldown)
                glColor3ub(255,255,0);
        else
-               glColor3ub(255,255,255);
-
-       glUseProgram(shaderProgram);
-       glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-       glBegin(GL_QUADS);
-               glTexCoord2i(0,1);glVertex2i(loc.x, loc.y);
-               glTexCoord2i(1,1);glVertex2i(loc.x + width, loc.y);
-               glTexCoord2i(1,0);glVertex2i(loc.x + width, loc.y + height);
-               glTexCoord2i(0,0);glVertex2i(loc.x, loc.y + height);
-       glEnd();
-       glUseProgram(0);
+               glColor3ub(255,255,255);*/
+
+               glUseProgram(worldShader);
+               glUniform1i(worldShader_uniform_texture, 0);
+               glEnableVertexAttribArray(worldShader_attribute_coord);
+               glEnableVertexAttribArray(worldShader_attribute_tex);
+
+               glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
+               if(left)
+                       glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coordL);
+               else
+                       glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coord);
+               glDrawArrays(GL_TRIANGLES, 0, 6);
 NOPE:
-       glDisable(GL_TEXTURE_2D);
-       glMatrixMode(GL_MODELVIEW);
-       glPopMatrix();
-       if (near && type != MOBT)
-               ui::putStringCentered(loc.x + width / 2, loc.y - ui::fontSize - game::HLINE / 2, name);
-       if (health != maxHealth) {
-               glColor3ub(150,0,0); glRectf(loc.x, loc.y + height, loc.x + width, loc.y + height + HLINES(2));
-               glColor3ub(255,0,0); glRectf(loc.x, loc.y + height, loc.x + width * (health / maxHealth), loc.y + height + HLINES(2));
-       }
+if (near && type != MOBT)
+       ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-game::HLINE/2,name);
+if (health != maxHealth) {
+
+       glBindTexture(GL_TEXTURE_2D,colorIndex);
+       glUniform1i(worldShader_uniform_texture, 0);
+
+       GLfloat coord_back[] = {
+               loc.x,                  loc.y + height,                         1.0,
+               loc.x + width,  loc.y + height,                         1.0,
+               loc.x + width,  loc.y + height + game::HLINE * 2, 1.0,
+
+               loc.x + width,  loc.y + height + game::HLINE * 2, 1.0,
+               loc.x,                  loc.y + height + game::HLINE * 2,       1.0,
+               loc.x,                  loc.y + height,                         1.0,
+       };
+
+       GLfloat coord_front[] = {
+               loc.x,                  loc.y + height,                         1.0,
+               loc.x + width,  loc.y + height,                         1.0,
+               loc.x + width,  loc.y + height + game::HLINE * 2, 1.0,
+
+               loc.x + width,  loc.y + height + game::HLINE * 2, 1.0,
+               loc.x,                  loc.y + height + game::HLINE * 2,       1.0,
+               loc.x,                  loc.y + height,                         1.0,
+       };
+
+       vec2 index = Texture::getIndex(Color(150,0,0));
+       GLfloat back_tex[] = {
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+       };
+       glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, coord_back);
+       glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, back_tex);
+       glDrawArrays(GL_TRIANGLES, 0, 6);
+
+       index = Texture::getIndex(Color(255,0,0));
+       GLfloat front_tex[] = {
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+               float(.25*index.x), float(.125*index.y),
+       };
+       glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, coord_front);
+       glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, front_tex);
+       glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+glDisableVertexAttribArray(worldShader_attribute_coord);
+glDisableVertexAttribArray(worldShader_attribute_tex);
+
+glUseProgram(0);
 }
 
 /**
@@ -786,16 +860,21 @@ Particles::Particles(float x, float y, float w, float h, float vx, float vy, Col
        index = Texture::getIndex(c);
 }
 
-void Particles::draw(void) const
+std::vector<std::pair<vec2, vec3>> Particles::draw(void) const
 {
-       glColor3ub(255, 255, 255);
-       glBegin(GL_QUADS);
-               vec2 tc = vec2 {0.25f * index.x, 0.125f * index.y};
-               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y);
-               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y);
-               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y + height);
-               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y + height);
-       glEnd();
+       vec2 tc = vec2 {0.25f * index.x, 0.125f * (8-index.y)};
+
+       std::vector<std::pair<vec2, vec3>> tmp;
+
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x,                 loc.y,               1.0)));
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x + width, loc.y,                   1.0)));
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x + width, loc.y + height,  1.0)));
+
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x + width, loc.y + height,  1.0)));
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x,         loc.y + height,  1.0)));
+       tmp.push_back(std::make_pair(vec2(tc.x, tc.y), vec3(loc.x,         loc.y,                   1.0)));
+
+       return tmp;
 }
 
 void Particles::update(float _gravity, float ground_y)
index eb6c3931b8091fffee1de7abdb3dfbea9fa96298..8d15bcd10e8d8608fb14cc0f7b32bff707094399 100644 (file)
@@ -276,7 +276,7 @@ namespace ui {
         *      Draws a character at the specified coordinates, aborting if the character is unknown.
        */
 
-       vec2 putChar(float xx,float yy,char c) {
+       vec2 putChar(float xx,float yy,char c){
                vec2 c1,c2;
 
                int x = xx, y = yy;
@@ -293,19 +293,48 @@ namespace ui {
                 *      Draw the character:
                */
 
-               glEnable(GL_TEXTURE_2D);
+               glActiveTexture(GL_TEXTURE0);
+               glUniform1i(textShader_uniform_texture, 0);
                glBindTexture(GL_TEXTURE_2D,(*ftex)[c-33]);
-               glPushMatrix();
-               glTranslatef(0,-c2.y,0);
-               glBegin(GL_QUADS);
-                       glColor4ub(fontColor[0],fontColor[1],fontColor[2],fontColor[3]);
-                       glTexCoord2f(0,1);glVertex2f(c1.x     ,c1.y             );
-                       glTexCoord2f(1,1);glVertex2f(c1.x+c2.x,c1.y             );
-                       glTexCoord2f(1,0);glVertex2f(c1.x+c2.x,c1.y+c2.y);
-                       glTexCoord2f(0,0);glVertex2f(c1.x     ,c1.y+c2.y);
-               glEnd();
-               glPopMatrix();
-               glDisable(GL_TEXTURE_2D);
+
+               //glDisable(GL_DEPTH_TEST);
+
+               glUseProgram(textShader);
+
+               glEnableVertexAttribArray(textShader_attribute_coord);
+               glEnableVertexAttribArray(textShader_attribute_tex);
+
+               GLfloat tex_coord[] = {
+                       0.0, 1.0,                               //bottom left
+                       1.0, 1.0,                               //bottom right
+                       1.0, 0.0,                               //top right
+
+                       1.0, 0.0,                               //top right
+                       0.0, 0.0,                               //top left
+                       0.0, 1.0,                               //bottom left
+
+               };
+
+               GLfloat text_vert[] = {
+                       c1.x,           c1.y     -c2.y, 1.0,    //bottom left
+                       c1.x+c2.x,      c1.y     -c2.y, 1.0,    //bottom right
+                       c1.x+c2.x,      c1.y+c2.y-c2.y, 1.0,    //top right
+
+                       c1.x+c2.x,      c1.y+c2.y-c2.y, 1.0,    //top right
+                       c1.x,           c1.y+c2.y-c2.y, 1.0,    //top left
+                       c1.x,           c1.y     -c2.y, 1.0,    //bottom left
+               };
+
+               glVertexAttribPointer(textShader_attribute_coord,       3, GL_FLOAT, GL_FALSE, 0, text_vert);
+               glVertexAttribPointer(textShader_attribute_tex,         2, GL_FLOAT, GL_FALSE, 0, tex_coord);
+               glDrawArrays(GL_TRIANGLES, 0, 6);
+
+               glDisableVertexAttribArray(textShader_attribute_tex);
+               glDisableVertexAttribArray(textShader_attribute_coord);
+
+               glUseProgram(0);
+
+               //glEnable(GL_DEPTH_TEST);
 
                // return the width.
                return (*ftdat)[c-33].ad;
@@ -610,19 +639,60 @@ namespace ui {
        }
 
        void drawBox(vec2 c1, vec2 c2) {
-               // draw black body
-               glColor3ub(0, 0, 0);
-               glRectf(c1.x, c1.y, c2.x, c2.y);
-
-               // draw white border
-               glColor3ub(255, 255, 255);
-               glBegin(GL_LINE_STRIP);
-                       glVertex2i(c1.x    , c1.y);
-                       glVertex2i(c2.x + 1, c1.y);
-                       glVertex2i(c2.x + 1, c2.y);
-                       glVertex2i(c1.x - 1, c2.y);
-                       glVertex2i(c1.x    , c1.y);
-               glEnd();
+        static vec2 lineIndexF = Texture::getIndex(Color(255, 255, 255));
+        static vec2 lineIndex = vec2(0.25f * lineIndexF.x, 0.125f * (8-lineIndexF.y));
+        static vec2 boxIndexF = Texture::getIndex(Color(0, 0, 0));
+        static vec2 boxIndex = vec2(0.25f * boxIndexF.x, 0.125f * (8-boxIndexF.y));
+
+        GLfloat box[] = {c1.x, c1.y, 1.0,
+                         c2.x, c1.y, 1.0,
+                         c2.x, c2.y, 1.0,
+
+                         c2.x, c2.y, 1.0,
+                         c1.x, c2.y, 1.0,
+                         c1.x, c1.y, 1.0};
+
+        GLfloat line_strip[] = {c1.x,     c1.y, 1.0,
+                                c2.x + 1, c1.y, 1.0,
+                                c2.x + 1, c2.y, 1.0,
+                                c1.x - 1, c2.y, 1.0,
+                                c1.x,     c1.y, 1.0};
+
+        static GLfloat box_tex[] = {boxIndex.x,boxIndex.y,
+                                    boxIndex.x,boxIndex.y,
+                                    boxIndex.x,boxIndex.y,
+
+                                    boxIndex.x,boxIndex.y,
+                                    boxIndex.x,boxIndex.y,
+                                    boxIndex.x,boxIndex.y};
+
+        static GLfloat line_tex[] = {lineIndex.x, lineIndex.y,
+                                     lineIndex.x, lineIndex.y,
+                                     lineIndex.x, lineIndex.y,
+                                     lineIndex.x, lineIndex.y,
+                                     lineIndex.x, lineIndex.y};
+
+        glActiveTexture(GL_TEXTURE9); 
+        glBindTexture(GL_TEXTURE_2D, colorIndex);
+        glUniform1i(textShader_uniform_texture, 9);
+        glUseProgram(textShader);
+
+        glEnableVertexAttribArray(textShader_attribute_coord);
+        glEnableVertexAttribArray(textShader_attribute_tex);
+   
+        glVertexAttribPointer(textShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, box);
+        glVertexAttribPointer(textShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, box_tex);
+        glDrawArrays(GL_TRIANGLES, 0 ,6);
+      
+        glVertexAttribPointer(textShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, line_strip);
+        glVertexAttribPointer(textShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, line_tex);
+        glDrawArrays(GL_LINE_STRIP, 0 ,5);
+
+        glDisableVertexAttribArray(textShader_attribute_coord);
+        glDisableVertexAttribArray(textShader_attribute_tex);
+        
+        glUseProgram(0);
+        glActiveTexture(GL_TEXTURE0);  
        }
 
        void draw(void){
index c08562069e53e92418d93c11341880658dba7731..c2cdbc5e7d71500c88bc5fe0f20f86fb04126703 100644 (file)
@@ -233,7 +233,7 @@ draw(Player *p)
     int iStart, iEnd;
 
     // shade value for draws -- may be unnecessary
-       int shadeBackground = -worldShade;
+       //int shadeBackground = -worldShade;
 
     // player's offset in worldData[]
        int pOffset;
@@ -250,11 +250,8 @@ draw(Player *p)
        if (shadeAmbient > 0.9f)
                shadeAmbient = 1;
 
-       // draw background images.
-       glEnable(GL_TEXTURE_2D);
 
        // the sunny wallpaper is faded with the night depending on tickCount
-       bgTex(0);
     switch (weather) {
     case WorldWeather::Snowy:
         alpha = 150;
@@ -266,85 +263,227 @@ draw(Player *p)
         alpha = 255 - worldShade * 4;
         break;
     }
+    (void)alpha;
+
+    glActiveTexture(GL_TEXTURE0);
+    glUniform1i(worldShader_uniform_texture, 0);
+
+    // draw background images.
+    //glEnable(GL_TEXTURE_2D);
+
+    GLfloat tex_coord[] = { 0.0f, 1.0f,
+                            1.0f, 1.0f,
+                            1.0f, 0.0f,
 
-       safeSetColorA(255, 255, 255, alpha);
+                            1.0f, 0.0f,
+                            0.0f, 0.0f,
+                            0.0f, 1.0f,};
+
+    vec2 bg_tex_coord[] = { vec2(0.0f, 0.0f),
+                            vec2(1.0f, 0.0f),
+                            vec2(1.0f, 1.0f),
+
+                            vec2(1.0f, 1.0f),
+                            vec2(0.0f, 1.0f),
+                            vec2(0.0f, 0.0f)};
+
+       /*safeSetColorA(255, 255, 255, alpha);
        glBegin(GL_QUADS);
                glTexCoord2i(0, 0); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y);
                glTexCoord2i(1, 0); glVertex2i(offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y);
                glTexCoord2i(1, 1); glVertex2i(offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y);
                glTexCoord2i(0, 1); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y);
-       glEnd();
+       glEnd();*/
+
+    bgTex(0);
+    GLfloat back_tex_coord[] = {offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 1.0f,
+                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 1.0f,
+                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 1.0f,
+
+                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 1.0f,
+                                offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 1.0f,
+                                offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 1.0f};
+
+    glUseProgram(worldShader);
+
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, back_tex_coord);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, tex_coord);
+    glDrawArrays(GL_TRIANGLES, 0 , 6);
+
+    glDisableVertexAttribArray(worldShader_attribute_coord);
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+
+    glUseProgram(0);
+
 
        bgTex++;
-       safeSetColorA(255, 255, 255, !alpha ? 255 : worldShade * 4);
+    //TODO
+    //glDrawArrays(GL_TRIANGLES, 0 , 6);
+
+    // TODO fade and draw night bg
+       /*safeSetColorA(255, 255, 255, !alpha ? 255 : worldShade * 4);
        glBegin(GL_QUADS);
         glTexCoord2i(0, 0); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y);
         glTexCoord2i(1, 0); glVertex2i(offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y);
         glTexCoord2i(1, 1); glVertex2i(offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y);
         glTexCoord2i(0, 1); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y);
-       glEnd();
+       glEnd();*/
 
-       glDisable(GL_TEXTURE_2D);
+       //glDisable(GL_TEXTURE_2D);
 
        // draw the stars if the time deems it appropriate
-       if (worldShade > 0) {
+       /*if (worldShade > 0) {
                safeSetColorA(255, 255, 255, 255 - (randGet() % 30 - 15));
 
         auto xcoord = offset.x * 0.9f;
                for (auto &s : star)
                        glRectf(s.x + xcoord, s.y, s.x + xcoord + HLINE, s.y + HLINE);
-       }
+       }*/
 
        // draw remaining background items
-       glEnable(GL_TEXTURE_2D);
+       //glEnable(GL_TEXTURE_2D);
+
+    std::vector<vec3> bg_items;
 
        bgTex++;
-       safeSetColorA(150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255);
-       glBegin(GL_QUADS); {
-        auto xcoord = width / 2 * -1 + offset.x * 0.85f;
-               for (unsigned int i = 0; i <= worldData.size() * HLINE / 1920; i++) {
-                       glTexCoord2i(0, 1); glVertex2i(1920 * i       + xcoord, GROUND_HEIGHT_MINIMUM);
-            glTexCoord2i(1, 1); glVertex2i(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM);
-                       glTexCoord2i(1, 0); glVertex2i(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + 1080);
-                       glTexCoord2i(0, 0); glVertex2i(1920 * i       + xcoord, GROUND_HEIGHT_MINIMUM + 1080);
-               }
-       } glEnd();
+       //safeSetColorA(150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255);
+    auto xcoord = width / 2 * -1 + offset.x * 0.85f;
+       for (unsigned int i = 0; i <= worldData.size() * HLINE / 1920; i++) {
+        bg_items.push_back(vec3(1920 * i       + xcoord, GROUND_HEIGHT_MINIMUM, 1.0f));
+        bg_items.push_back(vec3(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM, 1.0f));
+        bg_items.push_back(vec3(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + 1080, 1.0f));
+
+        bg_items.push_back(vec3(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + 1080, 1.0f));
+        bg_items.push_back(vec3(1920 * i       + xcoord, GROUND_HEIGHT_MINIMUM + 1080, 1.0f));
+        bg_items.push_back(vec3(1920 * i       + xcoord, GROUND_HEIGHT_MINIMUM, 1.0f));
+       }
+
+    std::vector<GLfloat> bg_i;
+    std::vector<GLfloat> bg_tx;
+
+    for (auto &v : bg_items) {
+        bg_i.push_back(v.x);
+        bg_i.push_back(v.y);
+        bg_i.push_back(v.z);
+    }
+
+    for (uint i = 0; i < bg_items.size()/6; i++) {
+        for (auto &v : bg_tex_coord) {
+            bg_tx.push_back(v.x);
+            bg_tx.push_back(v.y);
+        }
+    }
+
+    glUseProgram(worldShader);
+
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &bg_i[0]);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &bg_tx[0]);
+    glDrawArrays(GL_TRIANGLES, 0 , bg_items.size());
+
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+       glDisableVertexAttribArray(worldShader_attribute_coord);
+
+    glUseProgram(0);
+
+    //GARNBSFJBSJOFBSJDVFJDSF
 
        for (unsigned int i = 0; i < 4; i++) {
+        std::vector<vec3>c;
                bgTex++;
-               safeSetColorA(bgDraw[i][0] + shadeBackground * 2,
+               /*safeSetColorA(bgDraw[i][0] + shadeBackground * 2,
                       bgDraw[i][0] + shadeBackground * 2,
                       bgDraw[i][0] + shadeBackground * 2,
                       bgDraw[i][1]
-                      );
-               glBegin(GL_QUADS); {
-            auto xcoord = offset.x * bgDraw[i][2];
-                       for (int j = worldStart; j <= -worldStart; j += 600) {
-                glTexCoord2i(0, 1); glVertex2i(j       + xcoord, GROUND_HEIGHT_MINIMUM);
-                               glTexCoord2i(1, 1); glVertex2i(j + 600 + xcoord, GROUND_HEIGHT_MINIMUM);
-                               glTexCoord2i(1, 0); glVertex2i(j + 600 + xcoord, GROUND_HEIGHT_MINIMUM + 400);
-                               glTexCoord2i(0, 0); glVertex2i(j       + xcoord, GROUND_HEIGHT_MINIMUM + 400);
-                       }
-               } glEnd();
+                  );*/
+        auto xcoord = offset.x * bgDraw[i][2];
+               for (int j = worldStart; j <= -worldStart; j += 600) {
+            c.push_back(vec3(j       + xcoord, GROUND_HEIGHT_MINIMUM, 1));
+            c.push_back(vec3(j + 600 + xcoord, GROUND_HEIGHT_MINIMUM, 1));
+            c.push_back(vec3(j + 600 + xcoord, GROUND_HEIGHT_MINIMUM + 400, 1));
+
+            c.push_back(vec3(j + 600 + xcoord, GROUND_HEIGHT_MINIMUM + 400, 1));
+            c.push_back(vec3(j       + xcoord, GROUND_HEIGHT_MINIMUM + 400, 1));
+            c.push_back(vec3(j       + xcoord, GROUND_HEIGHT_MINIMUM, 1));
+               }
+
+        bg_i.clear();
+        bg_tx.clear();
+
+        for (auto &v : c) {
+            bg_i.push_back(v.x);
+            bg_i.push_back(v.y);
+            bg_i.push_back(v.z);
+        }
+
+        for (uint i = 0; i < c.size()/6; i++) {
+            for (auto &v : bg_tex_coord) {
+                bg_tx.push_back(v.x);
+                bg_tx.push_back(v.y);
+            }
+        }
+
+        glUseProgram(worldShader);
+
+        glEnableVertexAttribArray(worldShader_attribute_coord);
+        glEnableVertexAttribArray(worldShader_attribute_tex);
+
+        glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &bg_i[0]);
+        glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &bg_tx[0]);
+        glDrawArrays(GL_TRIANGLES, 0 , c.size());
+
+        glDisableVertexAttribArray(worldShader_attribute_tex);
+       glDisableVertexAttribArray(worldShader_attribute_coord);
+
+        glUseProgram(0);
        }
 
-       glDisable(GL_TEXTURE_2D);
+       //glDisable(GL_TEXTURE_2D);
 
        // draw black under backgrounds (y-coordinate)
-       glColor3ub(0, 0, 0);
-       glRectf(worldStart, GROUND_HEIGHT_MINIMUM, -worldStart, 0);
+       //glColor3ub(0, 0, 0);
+       //glRectf(worldStart, GROUND_HEIGHT_MINIMUM, -worldStart, 0);
 
        // draw particles and buildings
-    glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, colorIndex);
-    glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-    glUseProgram(shaderProgram);
+    glUniform1i(worldShader_uniform_texture, 0);
+    glUseProgram(worldShader);
+
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    std::vector<std::vector<std::pair<vec2, vec3>>> partv(0);
+    std::vector<GLfloat> partc(0);
+    std::vector<GLfloat> partt(0);
 
     for (auto &p : particles) {
         if (p.behind)
-            p.draw();
+            partv.push_back(p.draw());
+    }
+
+    for (auto &pv : partv) {
+        for (auto &v : pv){
+            partc.push_back(v.second.x);
+            partc.push_back(v.second.y);
+            partc.push_back(v.second.z);
+            
+            partt.push_back(v.first.x);
+            partt.push_back(v.first.y);
+        }
     }
 
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &partc[0]);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &partt[0]);
+    glDrawArrays(GL_TRIANGLES, 0, partc.size()/3);
+
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+    glDisableVertexAttribArray(worldShader_attribute_coord);
+
     glUseProgram(0);
 
        for (auto &b : build) {
@@ -374,11 +513,10 @@ draw(Player *p)
     }
 
     // draw light elements
-    glEnable(GL_TEXTURE_2D);
-    glActiveTexture(GL_TEXTURE0);
-    bgTex++;
+    //glEnable(GL_TEXTURE_2D);
+    //glActiveTexture(GL_TEXTURE0);
 
-    std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size()));
+    /*std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size()));
        auto pointArray = pointArrayBuf.get();
     GLfloat flameArray[64];
 
@@ -396,12 +534,9 @@ draw(Player *p)
         flameArray[i] = light[i].fireFlicker;
     }
 
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-       glUseProgram(shaderProgram);
-       glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-       glUniform1f(glGetUniformLocation(shaderProgram, "amb"), shadeAmbient);
+       //glUseProgram(shaderProgram);
+       //glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
+       //glUniform1f(glGetUniformLocation(shaderProgram, "amb"), shadeAmbient);
 
        if (light.empty())
                glUniform1i(glGetUniformLocation(shaderProgram, "numLight"), 0);
@@ -410,7 +545,10 @@ draw(Player *p)
                glUniform2fv(glGetUniformLocation(shaderProgram, "lightLocation"), light.size(), pointArray);
                glUniform3f (glGetUniformLocation(shaderProgram, "lightColor"), 1.0f, 1.0f, 1.0f);
         glUniform1fv(glGetUniformLocation(shaderProgram,"fireFlicker"), light.size(),flameArray);
-       }
+       }*/
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
     // get the line that the player is currently standing on
     pOffset = (offset.x + p->width / 2 - worldStart) / HLINE;
@@ -418,80 +556,193 @@ draw(Player *p)
     // only draw world within player vision
     iStart = static_cast<int>(fmax(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS, 0));
     iEnd   = static_cast<int>(fmin(pOffset + (SCREEN_WIDTH / 2 / HLINE) + GROUND_HILLINESS + HLINE, worldData.size()));
-    iEnd = static_cast<int>(fmax(iEnd, GROUND_HILLINESS));
+    iEnd   = static_cast<int>(fmax(iEnd, GROUND_HILLINESS));
+
+
+
+       //glBegin(GL_QUADS);
+    //std::for_each(std::begin(worldData) + iStart, std::begin(worldData) + iEnd, [&](WorldData wd) {
 
     // draw the dirt
-       glBegin(GL_QUADS);
-        //std::for_each(std::begin(worldData) + iStart, std::begin(worldData) + iEnd, [&](WorldData wd) {
-        for (int i = iStart; i < iEnd; i++) {
-            if (worldData[i].groundHeight <= 0) {
-                worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
-                glColor4ub(0, 0, 0, 255);
-            } else {
-                safeSetColorA(150, 150, 150, 255);
-            }
+    bgTex++;
+    std::vector<std::pair<vec2,vec3>> c;
+
+    for (int i = iStart; i < iEnd; i++) {
+        if (worldData[i].groundHeight <= 0) {
+            worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
+            glColor4ub(0, 0, 0, 255);
+        } else {
+            safeSetColorA(150, 150, 150, 255);
+        }
 
-            int ty = worldData[i].groundHeight / 64 + worldData[i].groundColor;
-            glTexCoord2i(0, 0);  glVertex2i(worldStart + i * HLINE         , worldData[i].groundHeight - GRASS_HEIGHT);
-            glTexCoord2i(1, 0);  glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT);
-            glTexCoord2i(1, ty); glVertex2i(worldStart + i * HLINE + HLINE, 0);
-            glTexCoord2i(0, ty); glVertex2i(worldStart + i * HLINE           , 0);
+        int ty = worldData[i].groundHeight / 64 + worldData[i].groundColor;
+        // glTexCoord2i(0, 0);  glVertex2i(worldStart + i * HLINE         , worldData[i].groundHeight - GRASS_HEIGHT);
+        // glTexCoord2i(1, 0);  glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT);
+        // glTexCoord2i(1, ty); glVertex2i(worldStart + i * HLINE + HLINE, 0);
+        // glTexCoord2i(0, ty); glVertex2i(worldStart + i * HLINE            , 0);
 
-            if (worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
-                worldData[i].groundHeight = 0;
-        }//);
-       glEnd();
+        c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + i * HLINE,         worldData[i].groundHeight - GRASS_HEIGHT, 1.0f)));
+        c.push_back(std::make_pair(vec2(1, 0), vec3(worldStart + i * HLINE + HLINE, worldData[i].groundHeight - GRASS_HEIGHT, 1.0f)));
+        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + i * HLINE + HLINE, 0,                                        1.0f)));
 
-       glUseProgram(0);
-       glDisable(GL_TEXTURE_2D);
+        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + i * HLINE + HLINE, 0,                                        1.0f)));
+        c.push_back(std::make_pair(vec2(0, ty),vec3(worldStart + i * HLINE,         0,                                        1.0f)));
+        c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + i * HLINE,         worldData[i].groundHeight - GRASS_HEIGHT, 1.0f)));
+
+        if (worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
+            worldData[i].groundHeight = 0;
+    }
+
+    std::vector<GLfloat> dirtc;
+    std::vector<GLfloat> dirtt;
+
+    for (auto &v : c) {
+        dirtc.push_back(v.second.x);
+        dirtc.push_back(v.second.y);
+        dirtc.push_back(v.second.z);
+
+        dirtt.push_back(v.first.x);
+        dirtt.push_back(v.first.y);
+    }
+
+    glUseProgram(worldShader);
+
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &dirtc[0]);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &dirtt[0]);
+    glDrawArrays(GL_TRIANGLES, 0 , c.size());
+
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+       glDisableVertexAttribArray(worldShader_attribute_coord);
+
+    glUseProgram(0);
+
+
+       //glEnd();
+
+       //glUseProgram(0);
 
        // draw the grass
-       glEnable(GL_TEXTURE_2D);
-       glActiveTexture(GL_TEXTURE0);
+       //glEnable(GL_TEXTURE_2D);
+       //glActiveTexture(GL_TEXTURE0);
        bgTex++;
-       glUseProgram(shaderProgram);
-       glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
+       //glUseProgram(shaderProgram);
+       //glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
     safeSetColorA(255, 255, 255, 255);
 
+    c.clear();
+    std::vector<GLfloat> grassc;
+    std::vector<GLfloat> grasst;
+
        for (int i = iStart; i < iEnd; i++) {
         auto wd = worldData[i];
         auto gh = wd.grassHeight;
 
                // flatten the grass if the player is standing on it.
-               if (!wd.grassUnpressed) {
-                       gh[0] /= 4;
+       if (!wd.grassUnpressed) {
+               gh[0] /= 4;
                        gh[1] /= 4;
                }
 
                // actually draw the grass.
         if (wd.groundHeight) {
-               glBegin(GL_QUADS);
-                       glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE            , wd.groundHeight + gh[0]);
+               //glBegin(GL_QUADS);
+                       /*glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE            , wd.groundHeight + gh[0]);
                        glTexCoord2i(1, 0); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[0]);
                        glTexCoord2i(1, 1); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT);
                        glTexCoord2i(0, 1); glVertex2i(worldStart + i * HLINE                , wd.groundHeight - GRASS_HEIGHT);
-                       glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[1]);
+
+                glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[1]);
                        glTexCoord2i(1, 0); glVertex2i(worldStart + i * HLINE + HLINE    , wd.groundHeight + gh[1]);
                        glTexCoord2i(1, 1); glVertex2i(worldStart + i * HLINE + HLINE    , wd.groundHeight - GRASS_HEIGHT);
-                       glTexCoord2i(0, 1); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT);
-               glEnd();
+                       glTexCoord2i(0, 1); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT);*/
+
+                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + i * HLINE            , wd.groundHeight + gh[0])));
+                c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[0])));
+                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT)));
+
+                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT)));
+                c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + i * HLINE                   , wd.groundHeight - GRASS_HEIGHT)));
+                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + i * HLINE            , wd.groundHeight + gh[0])));
+
+
+                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[1])));
+                c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + i * HLINE + HLINE    , wd.groundHeight + gh[1])));
+                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + i * HLINE + HLINE    , wd.groundHeight - GRASS_HEIGHT)));
+
+                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + i * HLINE + HLINE    , wd.groundHeight - GRASS_HEIGHT)));
+                c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT)));
+                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[1])));
+
+            //glEnd();
         }
        }
 
-       glUseProgram(0);
-       glDisable(GL_TEXTURE_2D);
+    for (auto &v : c) {
+        grassc.push_back(v.second.x);
+        grassc.push_back(v.second.y);
+        grassc.push_back(v.second.z);
+
+        grasst.push_back(v.first.x);
+        grasst.push_back(v.first.y);
+    }
+
+    glUseProgram(worldShader);
+
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &grassc[0]);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &grasst[0]);
+    glDrawArrays(GL_TRIANGLES, 0 , c.size());
+
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+    glDisableVertexAttribArray(worldShader_attribute_coord);
+
+    glUseProgram(0);
+
+
+       //glUseProgram(0);
+       //glDisable(GL_TEXTURE_2D);
 
        // draw particles
-    glActiveTexture(GL_TEXTURE0);
+
     glBindTexture(GL_TEXTURE_2D, colorIndex);
-    glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-    glUseProgram(shaderProgram);
+    glUniform1i(worldShader_uniform_texture, 0);
+    glUseProgram(worldShader);
 
-       for (auto &p : particles) {
+    glEnableVertexAttribArray(worldShader_attribute_coord);
+    glEnableVertexAttribArray(worldShader_attribute_tex);
+
+    partv.clear();
+    partc.clear();
+    partt.clear();
+
+    for (auto &p : particles) {
         if (!p.behind)
-            p.draw();
+            partv.push_back(p.draw());
+    }
+
+    for (auto &pv : partv) {
+        for (auto &v : pv){
+            partc.push_back(v.second.x);
+            partc.push_back(v.second.y);
+            partc.push_back(v.second.z);
+            
+            partt.push_back(v.first.x);
+            partt.push_back(v.first.y);
+        }
     }
 
+    glVertexAttribPointer(worldShader_attribute_coord, 3, GL_FLOAT, GL_FALSE, 0, &partc[0]);
+    glVertexAttribPointer(worldShader_attribute_tex, 2, GL_FLOAT, GL_FALSE, 0, &partt[0]);
+    glDrawArrays(GL_TRIANGLES, 0, partc.size()/3);
+
+    glDisableVertexAttribArray(worldShader_attribute_tex);
+    glDisableVertexAttribArray(worldShader_attribute_coord);
+
     glUseProgram(0);
 
     // draw remaining entities