Hi,
I started to work at Pong game in c++ with OpenGL. I've created the classes, and I tried for the moment to draw the ball on the screen.Here is my code:
VertexBuffer (Vbo):
#include "VBO.h"
Vbo::Vbo()
{
}
void Vbo::Init(GLuint nrOfVbos)
{
this->m_nrOfVbos = nrOfVbos;
glGenBuffers(this->m_nrOfVbos, &this->m_vboID);
}
Vbo::~Vbo()
{
glDeleteBuffers(this->m_nrOfVbos, &this->m_vboID);
}
void Vbo::Bind(GLfloat *data)
{
glBindBuffer(GL_ARRAY_BUFFER, this->m_vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
}
ElementBuffer(Ebo):
#include "Ebo.h"
Ebo::Ebo()
{
}
void Ebo::Init(GLuint nrOfEbos)
{
this->m_nrOfEbos = nrOfEbos;
glGenBuffers(this->m_nrOfEbos, &this->m_eboID);
}
void Ebo::Bind(GLuint *indices)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_eboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
Ebo::~Ebo()
{
glDeleteBuffers(this->m_nrOfEbos, &this->m_eboID);
}
Array Buffer (Vao):
#include "VAO.h"
Vao::Vao()
{
}
void Vao::Init(GLuint nrOfVaos)
{
this->m_nrOfVaos = nrOfVaos;
glGenVertexArrays(this->m_nrOfVaos, &this->m_vaoID);
}
void Vao::Bind()
{
glBindVertexArray(this->m_vaoID);
}
void Vao::AttribPointer(GLuint index, GLuint componentsCount, GLuint stride, GLuint ptr)
{
glVertexAttribPointer(index, componentsCount, GL_FLOAT, GL_FALSE, stride * sizeof(GLfloat), (GLvoid*)(ptr * (sizeof(GLfloat))));
glEnableVertexAttribArray(index);
}
void Vao::UnBind()
{
glBindVertexArray(0);
}
Vao::~Vao()
{
glDeleteVertexArrays(this->m_nrOfVaos, &this->m_vaoID);
}
Texture:
#include "Texture.h"
#include <SOIL.h>
Texture::Texture()
{
}
void Texture::Init(GLuint nrOfTex, char* imgName)
{
this->m_nrOfTex = nrOfTex;
glGenTextures(this->m_nrOfTex, &this->m_texID);
glBindTexture(GL_TEXTURE_2D, this->m_texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int imgWidth, imgHeight;
unsigned char* image = SOIL_load_image(imgName, &imgWidth, &imgHeight, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture::Bind()
{
glBindTexture(GL_TEXTURE_2D, this->m_texID);
}
Pong:
#include "Pong.h"
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
Pong::Pong() : paddleSh("Shaders/vertex.vs", "Shaders/paddle.frag"), ballSh("Shaders/vertex.vs", "Shaders/ball.frag")
{
//Init buffers
this->paddle1.Init(1);
this->paddle2.Init(1);
this->ball.Init(1);
this->buffer.Init(1);
this->indexBuffer.Init(1);
//Bind paddle1 buffer
paddle1.Bind();
buffer.Bind(vertices);
indexBuffer.Bind(indices);
//Position
paddle1.AttribPointer(0, 3, 5, 0);
//Texture
paddle1.AttribPointer(1, 2, 5, 3);
paddle1.UnBind();
paddle2.Bind();
buffer.Bind(vertices);
indexBuffer.Bind(indices);
//Position
paddle2.AttribPointer(0, 3, 5, 0);
//Texture
paddle2.AttribPointer(1, 2, 5, 3);
paddle2.UnBind();
ball.Bind();
buffer.Bind(vertices);
indexBuffer.Bind(indices);
//Position
ball.AttribPointer(0, 3, 5, 0);
//Texture
ball.AttribPointer(1, 2, 5, 3);
ball.UnBind();
//Init texture
this->paddlesTex.Init(1, "images/paddle.png");
this->ballTex.Init(1, "images/sun.png");
}
void Pong::Draw()
{
this->ballSh.Use();
glm::mat4 model;
glm::mat4 view;
glm::mat4 proj;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::scale(model, glm::vec3(100.0f, 100.0f, 0.0f));
view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
proj= glm::perspective(45.0f, (float)800 / (float)600, 0.1f, 100.0f);
GLint modelLoc = glGetUniformLocation(this->ballSh.Program, "model");
GLint viewLoc = glGetUniformLocation(this->ballSh.Program, "view");
GLint projLoc = glGetUniformLocation(this->ballSh.Program, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
this->ballTex.Bind();
glUniform1i(glGetUniformLocation(this->ballSh.Program, "ballTexture"), 0);
this->ball.Bind();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//this->ball.UnBind();
}
Pong::~Pong()
{
this->ball.~Vao();
}
Main:
#include <iostream>
//GLEW
#define GLEW_STATIC
#include<glew.h>
//GLFW
#include <glfw3.h>
#include "Shader.h"
//#include "Camera.h"
#include <SOIL.h>
// GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Pong.h"
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mode);
const GLuint screenWidth = 800, screenHeight = 600;
Pong *pong;
int main()
{
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
// GLFW init
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWWindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "Snake OpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
}
glfwMakeContextCurrent(window);
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
glewInit();
// Initialize GLEW to setup the OpenGL Function pointers
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
}
int width, height;
glfwGetFramebufferSize(window, &width, &height);
// Define the viewport dimensions
glViewport(0, 0, screenWidth, screenHeight);
glEnable(GL_BLEND);// you enable blending function
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pong = new Pong();
while (!glfwWindowShouldClose(window))
{
//Check if any events have been activated(key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
pong->Draw();
glfwSwapBuffers(window);
}
pong->~Pong();
glfwTerminate();
return 0;
}
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
/* if (key > 0 && key < 1024)
{
if (action == GLFW_PRESS)
{
snake->Keys[key] = GL_TRUE;
}
else if (action == GLFW_RELEASE)
{
snake->Keys[key] = GL_FALSE;
}
}
*/
if (key == GLFW_KEY_W && action == GLFW_PRESS)
{
}
if (key == GLFW_KEY_S && action == GLFW_PRESS)
{
}
if (key == GLFW_KEY_D && action == GLFW_PRESS)
{
}
if (key == GLFW_KEY_A && action == GLFW_PRESS)
{
}
}
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 TexCoords;
//out vec3 Position;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = texCoords;
}
Fragment Shader for the ball:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D ballTexture;
void main()
{
color = texture(ballTexture, TexCoords);
}
It runs but it doesn't show anything.(just in case if somebody will ask why is in 3D, I wanted to make it :D ).
Wait for your suggestions.
Thank you!