Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I just started learning OpenGL by following https://learnopengl.com/Getting-started/Hello-Triangle, following the tutorial I wrote the code as per my understanding which compiles and does give me an output but instead of an orangish triangle it shows a white one. If I replace the shaderProgram() with the code from https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/2.1.hello_triangle/hello_triangle.cpp it works (shows the orange triangle), so I think I narrowed the problem to shader program compilation, I just couldn't find what's wrong with it, following is my code.
// Local Headers
#include "glitter.hpp"
// System Headers
#include <glad/glad.h>
#include <GLFW/glfw3.h>
// Standard Headers
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <iostream>
#include <memory>
void _delete_shader(const GLuint *shader)
{
if (!shader) return;
glDeleteShader(*shader);
delete shader;
}
using shader_t = std::unique_ptr<GLuint, decltype(&_delete_shader)>;
// window resize callback
void framebuffer_size_callback(GLFWwindow* , int width, int height)
{
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
shader_t compileShader(const char *source, GLenum shaderType)
{
auto shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader);
int success;
char log[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
throw std::runtime_error(log);
}
return shader_t(new GLuint {shader}, &_delete_shader);
}
shader_t vertexshader() try
{
static const char *source = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
)";
return compileShader(source, GL_VERTEX_SHADER);
}
catch(const std::exception& e)
{
printf("error in vertex shader, %s\n", e.what());
exit(-1);
}
shader_t fragmentShader() try
{
static const char *source = R"(
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
)";
return compileShader(source, GL_FRAGMENT_SHADER);
}
catch(const std::exception &e)
{
printf("error in fragment shader, %s\n", e.what());
exit(-1);
}
uint32_t shaderProgram() try
{
uint32_t program = glCreateProgram();
const auto vertexShader = ::vertexshader();
glAttachShader(program, *vertexShader);
const auto fragmentShader = ::fragmentShader();
glAttachShader(program, *fragmentShader);
glLinkProgram(program);
int success;
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success)
{
char log[512];
glGetProgramInfoLog(program, 512, nullptr, log);
throw std::runtime_error(log);
}
}
catch(const std::exception &e)
{
printf("error in shader program, %s\n", e.what());
exit(-1);
}
int main(int , char * [])
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
printf("Failed to create window\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
puts("Failed to initialize GLAD\n");
glfwTerminate();
return -1;
}
glViewport(0, 0, 800, 600);
float vertices[] =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
const auto shaderProgram = ::shaderProgram();
unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);
// copy vertices into gpu memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// how data should be interpreted
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
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);
// 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);
while (!glfwWindowShouldClose(window))
{
// inputs
processInput(window);
// paint color
glClearColor(.2f, .3f, .3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// final rendering step
glfwSwapBuffers(window);
// check for events
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
shaderProgram() never returns anything, so the name of your GL program object is just lost, and your shaderProgram local variable contains just some undefined value, hence you never use that program.
Note that such mistakes will be spotted by almost every decent compiler, just enable (and read) the warnings...
Related
I used openGL, GLEW and GLFW3. In openGl 3.0 mesa, the default shader was used and a white triangle was drawn. In 4.2, the screen was left black. No error messages were generated.
The issue is not due to mislabeling of a fragment shader as a vertex shader or vice versa.
The program contains 3 functions:
(1) compileShader, which is supposed to take in shader type and source code as std::string and return a shader ID with compiled code.
(2) createProgram, takes in the source code of a vertex shader and a fragment shader and returns a program ID with the shaders compiled and attached.
(3) And main, where both shader source codes are defined as strings.
Sorry and Thank you.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
static unsigned int compileShader(unsigned int type, std::string const& sourceCode){
unsigned int shaderId = glCreateShader(type);
const char* source = sourceCode.c_str();
glShaderSource(shaderId, 1, &source, nullptr);
glCompileShader(shaderId);
int result;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE){
if (type == GL_FRAGMENT_SHADER) std::cout<<"Fragment\n";
else std::cout<<"Vertex";
std::cout<<"SHADER COMPILATION FAILED!"<<std::endl;
int logLength;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);
char* infoLog = new char[logLength];
glGetShaderInfoLog(shaderId, logLength, NULL, infoLog);
std::cout<<infoLog<<std::endl;
delete[] infoLog;
glDeleteShader(shaderId);
return 0;
}
return shaderId;
}
static unsigned int createProgram(std::string const& vertexCode, std::string const& fragmentCode){
unsigned int vsId = compileShader(GL_VERTEX_SHADER, vertexCode);
unsigned int fsId = compileShader(GL_FRAGMENT_SHADER, fragmentCode);
unsigned int programId = glCreateProgram();
glAttachShader(programId, vsId);
glAttachShader(programId, fsId);
glLinkProgram(programId);
glValidateProgram(programId);
glDeleteShader(vsId);
glDeleteShader(fsId);
return programId;
}
int main()
{
GLFWwindow* window;
if (!glfwInit())
{
std::cout<<"GLFW initialization failed";
return -1;
}
///switches to opengl 4.2!
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
glewInit();
std::cout << "OpenGL " << glGetString(GL_VERSION) << "\n" << std::endl;
float positions[6] = {
0.5f, 0.5f,
-0.5f, 0.5f,
0.0f, 0.0f
};
unsigned int buffer = 1;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); //enables the xy attrib of position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib
std::string vertexSource = R"(
#version 330 core
layout(location=0) in vec4 position;
void main(){
gl_Position = position;
}
)";
std::string fragmentSource = R"(
#version 330 core
layout(location=0) out vec4 color;
void main(){
color = vec4(1.0, 0.0, 0.0, 1.0);
}
)";
unsigned int programId = createProgram(vertexSource, fragmentSource);
glUseProgram(programId);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
The issue is not the shader program, but you are using a core profile OpenGL Context (GLFW_OPENGL_CORE_PROFILE). Thus you have to create a named Vertex Array Object. The default VAO (0) is not valid in a core profile context.
Generate vertex array object name by glGenVertexArrays and create and bind the object by glBindVertexArray:
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); //enables the xy attrib of position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib
i try to paint simple triangle but i somehow can see the triangle
Here is my files
the window do created but no triangals in it dont know why
#include <iostream>
#include "GLFWManager.h"
#include <stdio.h>
#include <stdlib.h>
int main()
{
std::cout << "Hello World!\n";
GLFWManager gLFWManager;
gLFWManager.Init();
GLuint vbo;
GLuint vao;
GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
// second triangle
0.0f, -0.5f, 0.0f, // left
0.9f, -0.5f, 0.0f, // right
0.45f, 0.5f, 0.0f // top
};
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
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);
// 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);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
int shaderProgram = gLFWManager.createShader();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
while (!glfwWindowShouldClose(gLFWManager.window))
{
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(vao); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
glDrawArrays(GL_TRIANGLES, 0,6); // set the count to 3 since we're drawing 3 vertices
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(gLFWManager.window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
}
and this one :
#include "GLFWManager.h"
#include "stdio.h"
#include "stdlib.h"
int GLFWManager::windowHight = 300;
int GLFWManager::windowWidth = 300;
void GLFWManager::errorCallback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
void GLFWManager::windowSizeCallbackcallback(GLFWwindow* window, int width, int height)
{
if (width > 0 && height > 0) {
windowHight = height;
windowWidth = width;
}
}
static void KeyCallback(GLFWwindow* window, int key, int, int action, int mods)
{
switch (key)
{
case GLFW_KEY_ESCAPE:
{
if (action == GLFW_RELEASE)
{
glfwSetWindowShouldClose(window, GLFW_PRESS);
}
}
}
}
GLFWManager::GLFWManager()
{
window = nullptr;
}
GLFWManager::~GLFWManager()
{
}
void GLFWManager::Init()
{
glfwSetErrorCallback(GLFWManager::errorCallback);
if (!glfwInit())
{
exit(EXIT_FAILURE);
}
setWindowsHints();
createWindow();
glfwSetKeyCallback(window, KeyCallback);
glfwSetWindowSizeCallback(window, GLFWManager::windowSizeCallbackcallback);
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode->width - windowWidth) /2 , (vidmode->height - windowHight) /2);
glfwGetFramebufferSize(window, &windowWidth, &windowHight);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
loadGlad();
}
void GLFWManager::setWindowsHints()
{
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
}
void GLFWManager::createWindow()
{
window = glfwCreateWindow(windowWidth,windowHight, "Test", NULL, NULL);
if (!window)
{
exit(EXIT_FAILURE);
}
}
void GLFWManager::loadGlad()
{
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
fprintf(stderr, "Failed to initialize GLAD");
exit(EXIT_FAILURE);
}
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
const GLubyte* version = glGetString(GL_VERSION); // version as a string
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
}
int GLFWManager::createShader()
{
const char* vertexShaderSource = "#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* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
// build and compile our shader program
// ------------------------------------
// vertex shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n ",infoLog);
}
// fragment shader
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s \n",infoLog);
}
// link shaders
int 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);
printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n %s \n",infoLog);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return shaderProgram;
}
glVertexAttribPointer and glEnableVertexAttribArray specify and enable an array of vertex attribute data and sets states in the state vector of the currently bound Vertex Array Object.
You have to bind the vertex array object (glBindVertexArray) before you can specify the vertex arrays:
// Create vertex buffer object
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create Vertex array object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// specify array of generic vertex array data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
Note, before you call glVertexAttribPointer, the Vertex Array Object and the Vertex Buffer Object have to be bound, because glVertexAttribPointer associates the buffer which is currently bound to the ARRAY_BUFFER target, to the attribute with the specified index, in the state vector of the currently bound VAO.
I have written a small application that uses opengl for graphics and glfw for window handling. However, when I draw something different on the screen, the window is not updated unless I unfocus it and go back by alt tab for example or resize it. However, I tested the exact same program on a different computer and it worked perfectly, so it must be a problem with my computer or a bug with glfw, how can I fix/debug this?
Here is the code I used when debugging, nothing changes unless I alt tab:
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 800;
// Shaders
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()
{
// Init GLFW
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(WIDTH, HEIGHT, "Assignment1", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Set the required callback functions, this is for input from the keyboard
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;
// Initialize GLEW to setup the OpenGL Function pointers
glewInit();
// Define the viewport dimensions
glViewport(0, 0, WIDTH, 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\n" << 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\n" << 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\n" << 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);
glBindBuffer(GL_ARRAY_BUFFER, 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
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// Game loop
int mo = 0;
auto mode = GL_LINE;
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
glBindVertexArray(VAO);
glUseProgram(shaderProgram);
glfwSwapInterval(3);
if (mo++ % 2)
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
mode = GL_LINE;
glfwMakeContextCurrent(window);
}
else
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glfwMakeContextCurrent(window);
mode = GL_FILL;
}
// Render
// Clear the colorbuffer
glClear(GL_COLOR_BUFFER_BIT);
// Draw our first triangle
glPolygonMode(GL_FRONT_AND_BACK, mode);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glBindVertexArray(0);
// Swap the screen buffers
}
// Properly de-allocate all resources once they've outlived their purpose
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
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);
}
The above code was used to test as many things as possible this may be easier to check, when pressing l or f nothing happens, but again alt tab or resizing will display the result:
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 800;
// Shaders
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";
auto type = GL_LINE;
int main()
{
// Init GLFW
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(WIDTH, HEIGHT, "Assignment1", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Set the required callback functions, this is for input from the keyboard
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;
// Initialize GLEW to setup the OpenGL Function pointers
glewInit();
// Define the viewport dimensions
glViewport(0, 0, WIDTH, 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\n" << 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\n" << 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\n" << 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);
glBindBuffer(GL_ARRAY_BUFFER, 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
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// Game loop
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
std::cout << type << "\n";
glUseProgram(shaderProgram);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw our first triangle
glPolygonMode(GL_FRONT_AND_BACK, type);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
// Swap the screen buffers
}
// Properly de-allocate all resources once they've outlived their purpose
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
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);
else if (key == GLFW_KEY_F)
{
type = GL_FILL;
}
else if (key == GLFW_KEY_L)
{
type = GL_LINE;
}
}
im learning about OpenGL and i wrote the following code in C++ using this guide and this video.
Also i am using GLFW for context creation and GLEW for GL functions
Most of the Shader class is copied from the video up linked,
The problem is that using glDrawElements() to render inside the main loop gets me a segmentation fault:
Segmentation fault
------------------
(program exited with code: 139)
Press return to continue
while with glDrawArrays() i can draw with no problems.
Does anyone know what this could be caused by?
I think the error might depend on the implementation of the Shader class, because i used glDrawArrays() in other programs that did not used this class and that cared about shaders in the main function.
program.cpp
//INCLUDE AND DECLARATIONS
#include <iostream>
#include <fstream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
#include "Shader.h"
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
unsigned long getFileLength(std::ifstream& file);
int loadshader(char* filename, GLchar** ShaderSource, unsigned long* len);
const GLuint WIDTH = 800, HEIGHT = 600;
//VERTEX DATA
float data[] = {
// X Y R G B
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
//main
int main()
{ //INIT GLFW AND WINDOW
glfwInit();
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);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glewExperimental = GL_TRUE;
glewInit();
glViewport(0, 0, WIDTH, HEIGHT);
//ALLOCATE BUFFERS
//VERTEX ARRAY BUFFER
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
//ELEMENT ARRAY BUFFER
GLuint ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
//CREATE SHADER
Shader shader("./shaders/basicShader");
// main loop
while (!glfwWindowShouldClose(window))
{
shader.Bind();
glfwPollEvents(); //window events
glClearColor(1.0f, 0.0f, 0.5f, 0.5f); //background
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window); //update window
}
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ebo);
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);
}
Shader.h
#include <iostream>
#include <fstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class Shader
{
public:
Shader(const std::string& filepath);
~Shader();
void Bind();
private:
static const GLuint NUM_SHADERS = 2;
GLuint program;
GLuint shaders[NUM_SHADERS];
std::string LoadShader(const std::string& fileName);
void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage);
GLuint CreateShader(const std::string& text, unsigned int type);
};
Shader.cpp
#include "Shader.h"
Shader::Shader(const std::string& filepath)
{
program = glCreateProgram();
shaders[0] = CreateShader(LoadShader(filepath + ".vs"), GL_VERTEX_SHADER);
shaders[1] = CreateShader(LoadShader(filepath + ".fs"), GL_FRAGMENT_SHADER);
for(unsigned int i = 0; i < NUM_SHADERS; i++)
{
glAttachShader(program, shaders[i]);
}
glBindAttribLocation(program, 0, "position");
glBindFragDataLocation(program, 0, "outColor");
glLinkProgram(program);
CheckShaderError(program, GL_LINK_STATUS, true, "Error linking shader program");
glValidateProgram(program);
CheckShaderError(program, GL_LINK_STATUS, true, "Invalid shader program");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLint posAttrib = glGetAttribLocation(program, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0);
glEnableVertexAttribArray(posAttrib);
GLint AttribColor = glGetAttribLocation(program, "color");
glVertexAttribPointer(AttribColor, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(2*sizeof(float)));
glEnableVertexAttribArray(AttribColor);
}
Shader::~Shader()
{
for(unsigned int i = 0; i < NUM_SHADERS; i++)
{
glDetachShader(program, shaders[i]);
glDeleteShader(shaders[i]);
}
glDeleteProgram(program);
}
void Shader::Bind()
{
glUseProgram(program);
}
//loads shaders from files
std::string Shader::LoadShader(const std::string& fileName)
{
std::ifstream file;
file.open((fileName).c_str());
std::string output;
std::string line;
if(file.is_open())
{
while(file.good())
{
getline(file, line);
output.append(line + "\n");
}
}
else
{
std::cerr << "Unable to load shader: " << fileName << std::endl;
}
return output;
}
//Checks for eventual errors in shaders
void Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
{
GLint success = 0;
GLchar error[1024] = { 0 };
if(isProgram)
glGetProgramiv(shader, flag, &success);
else
glGetShaderiv(shader, flag, &success);
if(success == GL_FALSE)
{
if(isProgram)
glGetProgramInfoLog(shader, sizeof(error), NULL, error);
else
glGetShaderInfoLog(shader, sizeof(error), NULL, error);
std::cerr << errorMessage << ": '" << error << "'" << std::endl;
}
}
GLuint Shader::CreateShader(const std::string& text, unsigned int type)
{
GLuint shader = glCreateShader(type);
if(shader == 0)
std::cerr << "error allocating shader" << std:: endl;
const GLchar* p[1];
p[0] = text.c_str();
GLint lengths[1];
lengths[0] = text.length();
glShaderSource(shader, 1, p, lengths);
glCompileShader(shader);
CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error compiling shader!");
return shader;
}
The problem is with your index buffer binding. The index buffer (GL_ELEMENT_ARRAY_BUFFER) binding is part of the VAO state. Skipping the unrelated calls, you have the following overall sequence:
...
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
...
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
...
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
Since the GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state, the current index buffer binding is replaced with the index buffer binding in the VAO state when you call:
glBindVertexArray(vao);
Since you never bind an index buffer while the VAO is bound, this means that the index buffer binding in the VAO state is 0. As a result, you don't have an index buffer bound after this call.
What happens next is that you make the glDrawElements() call with the last argument 0. Without an index buffer bound, the last argument is interpreted as a pointer to CPU memory. So OpenGL tries to read index data at address 0, which causes the crash.
To fix this, you simply have to bind the index buffer while the VAO is bound. You can either do that by changing the order of your calls, and create/bind the VAO before you set up the index buffer. Or you can bind it again when you set up the vertex attribute state. For example, at the very end of the Shader constructor, after the glVertexAttribPointer() and related calls, you add this call:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm trying to get screenWidth and screenHeight into my fragment shader through uniform variables. Here's my main.cpp where the offender lies, I can get the location (non -1) but when it actually sets the uniform variable thingy I segfault.
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "math_3d.h"
#include "shader.h"
// Global
GLuint VBO;
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void CreateVertexBuffer()
{
Vector3f Verticies[3];
Verticies[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Verticies[1] = Vector3f(1.0f, -1.0f, 0.0f);
Verticies[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verticies), Verticies, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test Window");
glutDisplayFunc(RenderSceneCB);
GLenum res = glewInit();
if(res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("Version: %s\n", version);
Shader vertexShader(GL_VERTEX_SHADER, "shader.vs");
Shader fragShader(GL_FRAGMENT_SHADER, "shader.fs");
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader.shader);
glAttachShader(program, fragShader.shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
printf("No link\n");
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE)
{
printf("No validate\n");
}
glUseProgram(program);
printf("UNIFORM\n");
// Set uniform variables
GLint location = glGetUniformLocation(program, "screenWidth");
printf("loc: %d\n", location);
glProgramUniform1i(program, location, 800);
/*
GLint location2 = glGetUniformLocation(program, "screenHeight");
printf("loc: %d\n", location2);
glProgramUniform1i(program, location2, 600);
printf("uniform done\n");
*/
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glPointSize(10.0f);
CreateVertexBuffer();
glutMainLoop();
return 0;
}
The shader looks like this:
#version 130
uniform int screenWidth = 800;
uniform int screenHeight = 600;
out vec4 FragColor;
void main()
{
FragColor = vec4(gl_FragCoord.x/screenWidth, gl_FragCoord.y/screenHeight, 0.0, 1.0);
}
Your problem is actually that glProgramUniform1i (...) is relatively new. You have not come out and stated your OpenGL version explicitly, but your shader targets GLSL 1.30 (OpenGL 3.0) so chances are very good your implementation does not understand that function.
That function started out life in the Direct State Access extension (GL_EXT_direct_state_access), where it goes by the name glProgramUniform1iEXT (...) and was promoted to core when Separate Shader Objects were (GL 4.1).
The only difference between the two functions (glUniform1i (...) and glProgramUniform1i{EXT} (...)) is that one uses the currently bound program object, and the other lets you pass the one you need.
Changed how I set the uniform variables to this and everything worked out. I changed glProgramUniform1i to glUniform1i and took away the program parameter.
Here's the final main.cpp, look for the uniform section to see my changes.
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "math_3d.h"
#include "shader.h"
// Global
GLuint VBO;
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void CreateVertexBuffer()
{
Vector3f Verticies[3];
Verticies[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Verticies[1] = Vector3f(1.0f, -1.0f, 0.0f);
Verticies[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verticies), Verticies, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test Window");
glutDisplayFunc(RenderSceneCB);
GLenum res = glewInit();
if(res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("Version: %s\n", version);
Shader vertexShader(GL_VERTEX_SHADER, "shader.vs");
Shader fragShader(GL_FRAGMENT_SHADER, "shader.fs");
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader.shader);
glAttachShader(program, fragShader.shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
printf("No link\n");
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE)
{
printf("No validate\n");
}
glUseProgram(program);
// Set uniform variables
GLint location = glGetUniformLocation(program, "screenWidth");
glUniform1i(location, 800);
GLint location2 = glGetUniformLocation(program, "screenHeight");
glUniform1i(location2, 600);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glPointSize(10.0f);
CreateVertexBuffer();
glutMainLoop();
return 0;
}