Friday, December 23, 2016

My C++/OpenGL "Hello Triangle" Code Does Not Draw A Triangle When Using SDL As A Window Library


I have been using the website Learn OpenGL but I am using SDL as a window Library.


My code seems to builds the window correctly but no triangle appears. I am compiling my code using Visual Studio 2013. I have spent many hours looking over the code but cannot see an error. Can anyone tell me where I have gone wrong?


#include 
#include

#include
#include
#include

#include

//***************************************************************************
// The Width of the screen
//***************************************************************************
const GLuint SCREEN_WIDTH = 800;

//***************************************************************************
// The height of the screen
//***************************************************************************

const GLuint SCREEN_HEIGHT = 600;

bool success = GL_TRUE;

const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";


const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";

int main(int argc, char *argv[])
{

//***********************************************************************
// Initialize SDL
//***********************************************************************
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL could not initialize!SDL Error :" <<
std::string(SDL_GetError());

return EXIT_FAILURE;
}

else
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);

SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);


//*******************************************************************
//The window we'll be rendering to
//*******************************************************************
SDL_Window *window = SDL_CreateWindow("Breakout",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
SCREEN_HEIGHT, SDL_WINDOW_SHOWN |
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

if (window == NULL)
{

std::cout << "Window could not be created!SDL_Error: " <<
std::string(SDL_GetError()) << std::endl;

return EXIT_FAILURE;
}

//*******************************************************************
//OpenGL context
//*******************************************************************
SDL_GLContext context = SDL_GL_CreateContext(window);


//*******************************************************************
// Set the required callback functions
//*******************************************************************
SDL_Event windowEvent;

//*******************************************************************
//Use OpenGL 3.3
//*******************************************************************


//*******************************************************************
// Set this to true so GLEW knows to use a modern approach to
// retrieving function pointers and extensions
//*******************************************************************
glewExperimental = GL_TRUE;

//*******************************************************************
// Initialize GLEW to setup the OpenGL Function pointers
//*******************************************************************
GLenum glewError = glewInit();

if (GLEW_OK != glewError)
{
std::cout << "Failed to initialize GLEW: " <<
glewGetErrorString(glewError) << std::endl;

return EXIT_FAILURE;
}

glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//*******************************************************************
// Define the viewport dimensions
//*******************************************************************
glViewport(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH, SCREEN_HEIGHT);

//*******************************************************************
// Build and compile our shader program

// Vertex shader
//*******************************************************************
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);

//*******************************************************************
// Check for compile time errors
//*******************************************************************
GLint success;

GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED: " <<
infoLog << std::endl;
}

//*******************************************************************

// Fragment shader
//*******************************************************************
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

//*******************************************************************
// Check for compile time errors
//*******************************************************************
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);

if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED: " <<
infoLog << std::endl;
}

//*******************************************************************
// Link shaders
//*******************************************************************

GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

//*******************************************************************
// Check for linking errors
//*******************************************************************
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {

glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

//*******************************************************************
// Set up vertex data (and buffer(s)) and attribute pointers
//*******************************************************************
GLfloat vertices[] = {

-0.5f, -0.5f, 0.0f, // Left
0.5f, -0.5f, 0.0f, // Right
0.0f, 0.5f, 0.0f // Top
};
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);

//*******************************************************************
// Bind the Vertex Array Object first, then bind and set vertex

// buffer(s) and attribute pointer(s).
//*******************************************************************
glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat),
(GLvoid*)0);


glEnableVertexAttribArray(0);

//*******************************************************************
// Note that this is allowed, the call to glVertexAttribPointer
// registered VBO as the currently bound vertex buffer object so
// afterwards we can safely unbind
//*******************************************************************
glBindBuffer(GL_ARRAY_BUFFER, 0);


//*******************************************************************
// Unbind VAO (it's always a good thing to unbind any buffer/array to
// prevent strange bugs)
//*******************************************************************
glBindVertexArray(0);

//*******************************************************************
// DeltaTime variables
//*******************************************************************
GLdouble deltaTime = 0.0f;

Uint64 lastFrame = 0L;
Uint64 currentFrame = SDL_GetPerformanceCounter();

while (true)
{
//***************************************************************
// Calculate delta time
//***************************************************************
lastFrame = currentFrame;
currentFrame = SDL_GetPerformanceCounter();


deltaTime = ((currentFrame - lastFrame) * 1000 /
(GLdouble)SDL_GetPerformanceFrequency());

double tmpDeltaTime = deltaTime;

//std::cout << "Hello 1 - deltaTime: " << std::to_string(deltaTime) <<
// std::endl;

if (SDL_PollEvent(&windowEvent))

{
if (windowEvent.type == SDL_QUIT)
{
break;
}
}

//***************************************************************
// Clear the colorbuffer and render
//***************************************************************

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

//***************************************************************
// Draw our first triangle
//***************************************************************
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);


//***************************************************************
// draw OpenGL: Swap the screen buffers
//***************************************************************
SDL_GL_SwapWindow(window);
}

//***************************************************************
// Properly de-allocate all resources once they've outlived their
// purpose

//***************************************************************
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);

SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
}

return EXIT_SUCCESS;

}

Answer



This line:


glViewport(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT);

... does not really make sense. You're passing in special constants only known by SDL to an OpenGL function that expects actual coordinates. If anything, I'd expect that to be glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT).


But then, I have never actually seen or used glViewport, and it looks like it's part of the deprecated fixed-function pipeline matrix stack, which you probably don't want to use since you're using shaders and VAOs. Simply remove the line, and voilĂ  ! Triangle.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...