Advertisement

C++/OpenGL Pong game rendering problems

Started by May 22, 2017 04:41 PM
2 comments, last by alx119 7 years, 6 months ago

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!

I stopped after reading the first file, as I found this:


void Ebo::Bind(GLuint *indices)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_eboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}

sizeof(indices) queries the size of a pointer variable, which is 4 or 8, depending on your architecture. That is barely enough to store a single float in. You may want to pass the actual size of the array along with the call, or better, use a std::vector or so, which can tell you its size. Bare pointers are very much obsolete.

Advertisement

As Alberth said, you're taking the size of a pointer. Pass in a unsigned int for the actual length of the array.

Or better yet, as he said use an std::vector to hold your points and pass that in, it has a length() function already in the class.

Though he did say bare pointers are obsolete that is absolutely not true at all. Unique, shared and weak pointers all have their place and should be used as a default in most cases, there is nothing wrong with using a naked pointer. A lot of times they're handy. Though as a beginner I would recommend becoming more advanced before playing with them as alternatives do exist. But they will not be removed from the standard anytime soon. We are here to teach and telling them pointers are now obsolete does nothing to help them, only hinder. The majority of source code they come across right now, at least in my experience, uses pointers. If you're using C++ you should learn to use them and their downsides too.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Hi,

Guys, I LOVE YOU SO MUCH :lol: :lol: .I Can't believe this, but this was the only mistake that I made. Thank you very very much. :D

This topic is closed to new replies.

Advertisement