系列四:Sprite 我爱精灵,我爱VBO

Posted unicornsir

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了系列四:Sprite 我爱精灵,我爱VBO相关的知识,希望对你有一定的参考价值。

经过前面几个系列的洗礼,对SDL及OPENGL有了很粗浅的认识

这次我们要升级了,钟爱的Sprite的闪现,先做个没有Shader的Spite,什么?

还有Shader?Shader是神马东东,别急,下一系列就会出现Shader

 

Sprite.h

技术图片
 1 #pragma once
 2 #include <gl/glew.h>
 3 
 4 class Sprite
 5 {
 6 public:
 7     Sprite();
 8     ~Sprite();
 9 
10     void init(float x, float y, float width, float height);
11     void draw();
12 
13 private:
14     float m_X;
15     float m_Y;
16     float m_Width;
17     float m_Height;
18 
19     GLuint m_vboID;
20 };
View Code

 

Sprite.cpp

技术图片
 1 #include "Sprite.h"
 2 
 3 
 4 Sprite::Sprite() :m_X(0.0f), m_Y(0.0f), m_Width(0.0f), m_Height(0.0f), m_vboID(0)
 5 {
 6 }
 7 
 8 
 9 Sprite::~Sprite()
10 {
11     if (m_vboID)
12     {
13         glDeleteBuffers(1, &m_vboID);
14     }
15 }
16 
17 void Sprite::init(float x, float y, float width, float height)
18 {
19     m_X = x;
20     m_Y = y;
21     m_Width = width;
22     m_Height = height;
23 
24     if (0 == m_vboID)
25     {
26         glGenBuffers(1, &m_vboID);
27     }
28 
29     //Hard code, vertex num: 6, xy:2
30     
31     //    v2         v1
32     //
33     //
34     //    v3
35     float vertexData[6 * 2];
36     //First Triangle
37     vertexData[0] = x + width;
38     vertexData[1] = y + height;
39 
40     vertexData[2] = x;
41     vertexData[3] = y + height;
42 
43     vertexData[4] = x;
44     vertexData[5] = y;
45     
46     //Second Triangle
47     vertexData[6] = x;
48     vertexData[7] = y;
49 
50     vertexData[8] = x + width;
51     vertexData[9] = y;
52 
53     vertexData[10] = x + width;
54     vertexData[11] = y + width;
55 
56 
57     glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
58     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
59 
60     glBindBuffer(GL_ARRAY_BUFFER, 0);
61 }
62 
63 void Sprite::draw()
64 {
65     glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
66 
67     glEnableVertexAttribArray(0);
68 
69     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
70     glDrawArrays(GL_TRIANGLES, 0, 6);
71 
72     glDisableVertexAttribArray(0);
73 
74     glBindBuffer(GL_ARRAY_BUFFER, 0);
75 }
View Code

 

MainGame.h

技术图片
 1 #pragma once
 2 #include <SDL/SDL.h>
 3 #include <GL/glew.h>
 4 #include "Sprite.h"
 5 
 6 enum class GameState{PLAY, EXIT};
 7 
 8 class MainGame
 9 {
10 public:
11     MainGame();
12     ~MainGame();
13 
14     void run();
15     
16 
17 private:
18     void initSystems();
19     void gameLoop();
20     void processInput();
21     void drawGame();
22 
23     SDL_Window* m_pWindow;
24     int m_nScreenWidth;
25     int m_nScreenHeight;
26     GameState m_gameState;
27     Sprite m_sprite;
28 };
View Code

 

MainGame.cpp

技术图片
  1 #include "MainGame.h"
  2 #include <iostream>
  3 #include <string>
  4 void faterError(const std::string& errorString)
  5 {
  6     std::cout << errorString << std::endl;
  7     std::cout << "Enter any key to quit...";
  8     std::cin.get();
  9     SDL_Quit();
 10 }
 11 
 12 MainGame::MainGame() :m_pWindow(nullptr), m_nScreenWidth(1024), m_nScreenHeight(768), m_gameState(GameState::PLAY)
 13 {
 14 
 15 }
 16 
 17 
 18 MainGame::~MainGame()
 19 {
 20 }
 21 
 22 void MainGame::run()
 23 {
 24     initSystems();
 25     m_sprite.init(-1.0f, -1.0f, 1.0f, 1.0f);
 26     gameLoop();
 27 }
 28 
 29 void MainGame::initSystems()
 30 {
 31     //Initialize SDL
 32     SDL_Init(SDL_INIT_EVERYTHING);
 33 
 34     //Open an SDL Window
 35     m_pWindow = SDL_CreateWindow("GraphicToturial", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_nScreenWidth, m_nScreenHeight, SDL_WINDOW_OPENGL);
 36     if (nullptr == m_pWindow)
 37     {
 38         faterError("SDL Window could not be created!");
 39     }
 40 
 41     //Set up our OpenGL Context
 42     SDL_GLContext glContext = SDL_GL_CreateContext(m_pWindow);
 43     if (nullptr == glContext)
 44     {
 45         faterError("SDL_GL context could not be created!");
 46     }
 47 
 48     //Set up glew (optional but recommend)
 49     glewExperimental = true;
 50     GLenum result = glewInit();
 51     if (GLEW_OK != result)
 52     {
 53         faterError("Could not initialize glew!");
 54     }
 55 
 56     //Tell SDL that we want a double buffered window so we dont get
 57     //any flickering
 58     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 59 
 60     glClearColor(0, 0, 1, 1);
 61 }
 62 
 63 void MainGame::gameLoop()
 64 {
 65     while (m_gameState != GameState::EXIT)
 66     {
 67         processInput();
 68         drawGame();
 69     }
 70 }
 71 
 72 void MainGame::processInput()
 73 {
 74     SDL_Event evnt;
 75     while (SDL_PollEvent(&evnt))
 76     {
 77         switch (evnt.type)
 78         {
 79         case SDL_QUIT:
 80             m_gameState = GameState::EXIT;
 81             break;
 82         case SDL_MOUSEMOTION:
 83             std::cout << evnt.motion.x << " " << evnt.motion.y << std::endl;
 84             break;
 85         }
 86     }
 87 }
 88 
 89 void MainGame::drawGame()
 90 {
 91     glClearDepth(1.0);
 92     //Clear the color and depth buffer
 93     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 94 
 95     //注意点1
 96     //Tell OpenGL we want to use color. (only needed for immediate mode)
 97     //glEnableClientState(GL_COLOR_ARRAY);
 98 
 99     m_sprite.draw();
100 
101     //Swap our buffer and draw everything to the screen!
102     SDL_GL_SwapWindow(m_pWindow);
103 }
View Code

 

***注意点:

当使用Modern OpenGL时,不能有glEnableClientState(GL_COLOR_ARRAY);否则就会Booooo!!!!

以上是关于系列四:Sprite 我爱精灵,我爱VBO的主要内容,如果未能解决你的问题,请参考以下文章

我爱java系列---自定义注解

我爱java系列---idea中如何使用git

我爱java系列---idea中如何使用git

我爱java系列---Docker的使用

我爱java系列---项目研发流程——一张图搞定

我爱java系列---消息队列(rabbitmq)