PDA

View Full Version : Does this run properly for anyone else?



SentientBag
06-10-2017, 02:13 PM
Hi everyone. This is my first OpenGL program, and I understand all of of the concepts (VAOs, VBOs, etc...) but just cannot get it to work.



//
// main.cpp
// opengl_rect_w_shader_header
//
// Created by Pramod on 21/05/2017.
// Copyright 2017 Pramod. All rights reserved.
//

#include <iostream>
#include <SDL2/SDL.h>
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>

SDL_GLContext context;
SDL_Window * window;

bool initWindow(){

if (SDL_Init(SDL_INIT_VIDEO)<0){
std::cout << "Can't make SDL" << std::endl;
}

//what version we are using
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_ACCELERATED_VISUAL, 1);

window = SDL_CreateWindow("Rectangle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_OPENGL);
if (!window){
std::cout << "No window created" << std::endl;
//window = NULL;
return false;
}

context = SDL_GL_CreateContext(window);
if (!context){
std::cout << "No context created" << std::endl;
return false;
}

//double buffering - 24bit z buffer (might need changing for different systems)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

//Makes buffer swap sync with VBLANK
SDL_GL_SetSwapInterval(1);

glViewport(0, 0, 512, 512);

std:: cout << "Initialised" << std::endl;

return true;
};

int main(int argc, const char * argv[]) {
initWindow();
/*
const char * vshaderFile = "vertex.txt";
const char * fshaderFile = "fragment.txt";
long length;
char * vertexBuf;

FILE * vertexFile = fopen(vshaderFile, "r");

if(!vertexFile) { std::cout << "Could not open vertex shader" << std::endl; }
fseek(vertexFile, 0, SEEK_END);
length = ftell(vertexFile);

vertexBuf = new char [length + 1];
fseek(vertexFile, 0, SEEK_SET);
fread(vertexBuf, length, 1, vertexFile);
fclose(vertexFile);
vertexBuf[length] = 0; //makes the terminating character null

//read fragment shader
long length2;
char * fragmentBuf;
FILE * fragmentFile = fopen(fshaderFile, "r");

if(!fragmentFile){ std::cout << "Could not open fragment shader" << std::endl; }
fseek(fragmentFile, 0, SEEK_END);
length2 = ftell(fragmentFile);

fragmentBuf = new char [length2 + 1];
fseek(fragmentFile, 0, SEEK_SET);
fread(fragmentBuf, length2, 1, fragmentFile);
fclose(fragmentFile);
fragmentBuf[length2] = 0;
*/

//makes the source pointers the buffers

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

const char *fShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
"}\n\0";

//compiles shaders

//fragment
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
//std::cout << glGetError() << std::endl;
glShaderSource(fragmentShader, 1, &fShaderSource, NULL);
glCompileShader(fragmentShader);
int success;
char infoLog[512];
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}

//vertex
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vShaderSource, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}


//releases buffers
//delete[] fragmentBuf;
//delete[] vertexBuf;
//fragmentBuf = NULL;
//vertexBuf = NULL;

//links program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);

glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}

//deletes unneeded shaders
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);

std:: cout << "Shaders complete" << std:: endl;
//std::cout << vShaderSource << std::endl << std::endl << fShaderSource << std::endl;

//================================================== ================================================== =============


GLfloat vertices[3][4] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
GLint indices[3][2] = { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};

GLuint VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof (float), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), indices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);

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

// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0);

bool loop = true;

glClearColor(0.5f, 0.1f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (void*)0);
//glBindVertexArray(0);
SDL_GL_SwapWindow(window);
std::cout << glGetError() << std::endl;
//std::cout << glCheckError() << std::endl;


while (loop) {
SDL_Event e;
while(SDL_PollEvent(&e)){
if (e.type == SDL_QUIT) loop = false;
if (e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_ESCAPE:
loop = false;
break;
case SDLK_y:
std::cout << glGetString(GL_VERSION) << std::endl;
break;
}
std::cout << "Error: " << SDL_GetError() << std::endl;
std::cout << glGetError() << std::endl;
}
}

}

}



I have spent at least 3 months looking at this and wondering why it doesn't work...

What happens when you run the program: Screen goes fuschia purple colour, but does not draw rectangle. I set the rectangle colour to white just to make sure it stood out against the background.
I made sure that I swap the buffer so that I can see the rectangle. I also checked every single function call against the prototypes and tutorials to make sure I had the right parameters.

GL version returned is 3.3, and error code is 0. SDL also returns no errors.

I can't see what I have done wrong compared to the tutorial https://learnopengl.com/#!Getting-started/Hello-Triangle ... Can someone else run this on their computer and see if the rectangle is drawn or not? (The code doesn't have the #ifdef stuff to make it work on both Windows and Mac/Linux, sorry). Thank you.

edit: FIXED! :D I changed GL_UNSIGNED_BYTE in the glDrawElements to GL_UNSIGNED_INT. Phew! Thank you everyone! My first rectangle (well, square...) at last....

OceanJeff40
06-11-2017, 09:37 PM
Could it be that your indices array is GLint, but your calling glDrawElements with GL_UNSIGNED_BYTE? Do you need to make them GLuint?

Jeff

OceanJeff40
06-12-2017, 10:16 AM
Yay. Awesome dude.

Glad to be of service.

Jeff