I'm moving my OpenGL project over from GLUT to GLFW. Currently I am trying to get text to appear on screen using the library FreeType. I am following the tutorials from their site, but I am stuck. I believe I have it all written out, but for some reason it isn't working. What am I missing?
Here is my code:
#include <iostream>
#include <stdlib.h>
// Include GLEW
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "ft2build.h"
#include FT_FREETYPE_H
FT_Library library;
FT_Face face;
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
//should only be used for key press or key release
static void key_press(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void render_text(const std::string &str, FT_Face face, float x, float y, float sx, float sy) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
const FT_GlyphSlot glyph = face->glyph;
for (auto c : str) {
if (FT_Load_Char(face, c, FT_LOAD_RENDER) != 0)
continue;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8,
glyph->bitmap.width, glyph->bitmap.rows,
0, GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer);
const float vx = x + glyph->bitmap_left * sx;
const float vy = y + glyph->bitmap_top * sy;
const float w = glyph->bitmap.width * sx;
const float h = glyph->bitmap.rows * sy;
struct {
float x, y, s, t;
} data[6] = {
{ vx, vy, 0, 0 },
{ vx, vy - h, 0, 1 },
{ vx + w, vy, 1, 0 },
{ vx + w, vy, 1, 0 },
{ vx, vy - h, 0, 1 },
{ vx + w, vy - h, 1, 1 }
};
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), data, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (glyph->advance.x >> 6) * sx;
y += (glyph->advance.y >> 6) * sy;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
void Resize(GLFWwindow* window)
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.f, 5.f, -5.f, 5.f, 5.f, -5.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Setup()
{
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); // Depth Testing
glDepthFunc(GL_LEQUAL);
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
//used for font
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void Display(GLFWwindow* window)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
render_text("TEST", face, 0, 0, 100, 100);
glfwSwapBuffers(window);
glfwPollEvents();
}
void Update(GLFWwindow* window)
{
Display(window);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
std::cout << "glewInit failed, aborting." << std::endl;
exit(EXIT_FAILURE);
}
FT_Error error = FT_Init_FreeType(&library);
if (error) {
fprintf(stderr, "Could not init freetype library\n");
return 1;
}
error = FT_New_Face(library, "Stoke-Regular.ttf", 0, &face);
if (error == FT_Err_Unknown_File_Format)
{
std::cout << "font is unsupported" << std::endl;
return 1;
}
else if (error)
{
std::cout << "font could not be read or opened" << std::endl;
return 1;
}
error = FT_Set_Pixel_Sizes(face, 0, 48);
if (error)
{
std::cout << "Problem adjusting pixel size" << std::endl;
return 1;
}
//keyboard controls
glfwSetKeyCallback(window, key_press);
Resize(window);
Setup();
while (!glfwWindowShouldClose(window))
{
Update(window);
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
Related
I am new to OpenGl, right now my code can move a big circle with a small one inside him around the window.
Can you please tell me how to move the small circle separately from the big one, and also how to get him out from inside the big one.
And when for eg.: the small cirle is inside the big one when they are moving they moving together, and there is a line which is connects the center of the window with the small cirlce.
Here is my code:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glm/glm.hpp"
#include <array>
#include <iostream>
#include <string>
#include <fstream>
#define PI 3.14159265359
using namespace std;
#define numVAOs 1
GLuint VBO;
GLuint VAO;
GLfloat radius = 0.2;
GLfloat centerx = 0.3;
GLfloat centery = 0;
GLfloat novX = 0.009;
GLfloat novY = 0.005;
GLdouble updateFrequency = 0.01, lastUpdate;
GLfloat s_vertices[600];
void updateVertexData()
{
for (int i = 0; i < 100; i++)
{
s_vertices[3 * i] = centerx + radius * cos(i * (2 * PI / 100));
s_vertices[3 * i + 1] = centery + radius * sin(i * (2 * PI / 100));
s_vertices[3 * i + 2] = 0;
}
}
void updateVertexData1()
{
for (int j = 100; j < 200; j++) {
s_vertices[3 * j] = centerx + radius * (cos(j * (2 * PI / 100))) / 5;
s_vertices[3 * j + 1] = centery + radius * (sin(j * (2 * PI / 100))) / 5;
s_vertices[3 * j + 2] = 0;
}
}
void updateVBO() {
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(s_vertices), s_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
GLuint renderingProgram;
GLuint vao[numVAOs];
bool checkOpenGLError() {
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "glError: " << glErr << endl;
foundError = true;
glErr = glGetError();
}
return foundError;
}
void printShaderLog(GLuint shader) {
int len = 0;
int chWrittn = 0;
char* log;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetShaderInfoLog(shader, len, &chWrittn, log);
cout << "Shader Info Log: " << log << endl;
free(log);
}
}
void printProgramLog(int prog) {
int len = 0;
int chWrittn = 0;
char* log;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetProgramInfoLog(prog, len, &chWrittn, log);
cout << "Program Info Log: " << log << endl;
free(log);
}
}
string readShaderSource(const char* filePath) {
string content;
ifstream fileStream(filePath, ios::in);
string line = "";
while (!fileStream.eof()) {
getline(fileStream, line);
content.append(line + "\n");
}
fileStream.close();
return content;
}
GLuint createShaderProgram() {
GLint vertCompiled;
GLint fragCompiled;
GLint linked;
string vertShaderStr = readShaderSource("vertexShader.glsl");
string fragShaderStr = readShaderSource("fragmentShader.glsl");
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* vertShaderSrc = vertShaderStr.c_str();
const char* fragShaderSrc = fragShaderStr.c_str();
glShaderSource(vShader, 1, &vertShaderSrc, NULL);
glShaderSource(fShader, 1, &fragShaderSrc, NULL);
glCompileShader(vShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
if (vertCompiled != 1) {
cout << "vertex compilation failed" << endl;
printShaderLog(vShader);
}
glCompileShader(fShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &fragCompiled);
if (fragCompiled != 1) {
cout << "fragment compilation failed" << endl;
printShaderLog(fShader);
}
GLuint vfProgram = glCreateProgram();
glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
checkOpenGLError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (linked != 1) {
cout << "linking failed" << endl;
printProgramLog(vfProgram);
}
glDeleteShader(vShader);
glDeleteShader(fShader);
return vfProgram;
}
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (action == GLFW_PRESS)
{
switch (key) {
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, GLFW_TRUE);
break;
case GLFW_KEY_L:
novX *= -1;
break;
case GLFW_KEY_R:
radius += 0.01;
updateVertexData();
updateVertexData1();
updateVBO();
break;
}
}
}
void cursorPosCallback(GLFWwindow* window, double xPos, double yPos)
{
}
void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
}
void init() {
renderingProgram = createShaderProgram();
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(s_vertices), s_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void cleanUpScene()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(renderingProgram);
}
void display(GLFWwindow* window, double currentTime) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
glUseProgram(renderingProgram);
glBindVertexArray(VAO);
glPointSize(8.0);
glDrawArrays(GL_LINE_LOOP, 0, 99);
glDrawArrays(GL_LINE_LOOP, 100, 200);
if (currentTime - lastUpdate >= updateFrequency) {
centerx += novX;
centery += novY;
if (centerx + radius > 1 - abs(novX) || centerx - radius < -1 + abs(novX))
novX *= -1;
if (centery + radius > 1 - abs(novY) || centery - radius < -1 + abs(novY))
novY *= -1;
lastUpdate = currentTime;
updateVertexData();
updateVertexData1();
updateVBO();
}
glBindVertexArray(0);
}
int main(void) {
updateVertexData();
updateVertexData1();
if (!glfwInit()) { exit(EXIT_FAILURE); }
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(600, 600, "VAO VBO", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
glfwSwapInterval(1);
init();
lastUpdate = glfwGetTime();
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
cleanUpScene();
glfwTerminate();
exit(EXIT_SUCCESS);
}
I'm beggining at modern OpenGL.
But I am front of a strange memory leak with VBO and VAO.
Here is my code ( the important part ) :
#include "OpenGlScene.h"
#include "Block.h"
#include <iostream>
#include "Shader.h"
#include "Camera2D.h"
#include "Input.h"
#include "Container.h"
#include "Texture.h"
OpenGlScene::OpenGlScene(void) {
this->width = 1280;
this->height = 720;
this->initWindow();
this->initOpenGl();
this->loop();
}
OpenGlScene::~OpenGlScene(void)
{
}
void OpenGlScene::loop() {
bool mustFinish = false;
unsigned int frameRate = ( 1000 / 60 );
int startTime, endTime, elapsedTime = 0;
Container* cContainer = new Container();
Input *iInput = new Input();
cContainer->setInput(iInput);
iInput->setContainer(cContainer);
Camera2D *cCamera = new Camera2D();
cContainer->setCamera(cCamera);
cCamera->setContainer(cContainer);
cCamera->init(this->width, this->height);
glm::mat4 cameraMatrix;
Block *bBlock = new Block(0,0);
bBlock->setContainer(cContainer);
bBlock->init();
Block *aBlock = new Block(-100, -100);
aBlock->setContainer(cContainer);
aBlock->init();
Block *cBlock = new Block(-200, -100);
cBlock->setContainer(cContainer);
cBlock->init();
//bBlock->load();
while(!mustFinish) {
startTime = SDL_GetTicks();
cCamera->update();
iInput->update();
bBlock->update();
cameraMatrix = cCamera->getCameraMatrix();
bBlock->render();
aBlock->render();
cBlock->render();
SDL_GL_SwapWindow(this->Window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
glClearColor(119/255.0f,181/255.0f,254/255.0f,1);
endTime = SDL_GetTicks();
elapsedTime = endTime - startTime;
if(elapsedTime < frameRate) {
SDL_Delay(frameRate - elapsedTime);
}
}
}
bool OpenGlScene::initOpenGl() {
GLenum glewInit( glewInit() );
if(glewInit != GLEW_OK)
{
std::cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(glewInit) << std::endl;
SDL_GL_DeleteContext(this->OpenGlContext);
SDL_DestroyWindow(this->Window);
SDL_Quit();
return false;
}
glEnable(GL_DEPTH_TEST);
return true;
}
bool OpenGlScene::initWindow() {
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Erreur lors de l'initialisation de la SDL : " << SDL_GetError() << std::endl;
SDL_Quit();
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
this->Window = SDL_CreateWindow("OpenGL Scene", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->width, this->height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if(this->Window == 0) {
std::cout << "Erreur lors de la creation de la fenetre : " << SDL_GetError() << std::endl;
SDL_Quit();
return false;
}
SDL_GLContext context = SDL_GL_CreateContext(this->Window);
this->OpenGlContext = &context;
if((*this->OpenGlContext) == 0) {
std::cout << SDL_GetError() << std::endl;
SDL_DestroyWindow(this->Window);
SDL_Quit();
return false;
}
return true;
}
The leak comes from the loop method inside the while.
It mostly comes from when I render Blocks.
#include "Block.h"
Block::Block(float x, float y){
this->time = 0.0f;
this->x = x;
this->y = y;
this->size = 200.0f;
this->sSprite = nullptr;
}
Block::~Block(void){
if(this->sSprite) {
delete this->sSprite;
}
}
void Block::init() {
this->sSprite = new SpriteRect(x, y, size, size, "textures/grass.png", 1.0f, 1.0f, 1.0f, 1.0f);
this->sSprite->setContainer(this->cContainer);
this->sSprite->load();
}
void Block::update() {
this->time += 0.5f;
this->x += 0.5f;
//this->sSprite->update(this->x, this->y);
}
void Block::render() {
this->sSprite->render();
}
And the most important, SpriteRect.cpp :
#include "SpriteRect.h"
#include <string>
#include "Texture.h"
#include "Shader.h"
#include "Container.h"
#include "Camera2D.h"
SpriteRect::SpriteRect(float x, float y, float width, float height, std::string textureFile, float r, float g, float b, float a) {
this->x = x;
this->y = y;
this->width = width;
this->height = height;
this->vaoId = 0;
this->vboId = 0;
this->tTexture = new Texture(textureFile);
this->tTexture->load();
this->cColor = new Color();
this->cColor->a = a;
this->cColor->r = r;
this->cColor->g = g;
this->cColor->b = b;
float textureCoordsTmp[] = {0.0f, 1, 1,1, 0.0f,0.0f,
0.0f,0.0f, 1,1, 1,0.0f};
float colorCoordsTmp[] = {this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a, this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a, this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a,
this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a, this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a, this->cColor->r,this->cColor->g,this->cColor->b,this->cColor->a};
for(int i = 0; i<12; i++) {
this->textureCoords[i] = textureCoordsTmp[i];
}
for(int i= 0; i<24;i++) {
this->colors[i] = colorCoordsTmp[i];
}
this->setVerticesFromCoords();
this->colorsSizeBytes = (24*sizeof(float));
this->textureCoordsSizeBytes = (12*sizeof(float));
this->verticesSizeBytes = (12*sizeof(float));
this->sShader = new Shader("Shaders/classic2D.vert", "Shaders/classic2D.frag");
this->sShader->charger();
}
SpriteRect::~SpriteRect() {
delete this->tTexture;
delete this->cColor;
delete this->sShader;
glDeleteBuffers(1, &vboId);
glDeleteVertexArrays(1, &vaoId);
}
void SpriteRect::setVerticesFromCoords() {
float verticesTmp[] = {x, y, x+width, y, x, y+height,
x, y+height, x+width, y, x+width, y+height};
for(int i=0;i<12;i++) {
this->vertices[i] = verticesTmp[i];
}
if(glIsBuffer(vboId) == GL_TRUE) {
this->updateVbo(this->vertices, 12*sizeof(float), 0);
}
}
void SpriteRect::load() {
if(glIsBuffer(vboId) == GL_TRUE) {
glDeleteBuffers(1, &vboId);
}
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, (this->verticesSizeBytes + this->colorsSizeBytes + this->textureCoordsSizeBytes), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, this->verticesSizeBytes, this->vertices);
glBufferSubData(GL_ARRAY_BUFFER, this->verticesSizeBytes, this->colorsSizeBytes, this->colors);
glBufferSubData(GL_ARRAY_BUFFER, this->verticesSizeBytes+this->colorsSizeBytes, this->textureCoordsSizeBytes, this->textureCoords);
glBindBuffer(GL_ARRAY_BUFFER, 0);
if(glIsVertexArray(vaoId)) {
glDeleteVertexArrays(1, &vaoId);
}
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(this->verticesSizeBytes));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(this->verticesSizeBytes+this->colorsSizeBytes));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void SpriteRect::update(float x, float y) {
if(x != this->x || y != this->y) {
this->x = x;
this->y = y;
this->setVerticesFromCoords();
}
this->update();
}
void SpriteRect::update() {
}
void SpriteRect::updateVbo(void *datas, int sizeBytes, int offset)
{
// Verrouillage du VBO
glBindBuffer(GL_ARRAY_BUFFER,vboId);
// Récupération de l'adresse du VBO
void *vboAdress = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
// Si l'adresse retournée est nulle alors on arrête le transfert
if(vboAdress == NULL)
{
std::cout << "Erreur au niveau de la récupération du VBO" << std::endl;
glBindBuffer(GL_ARRAY_BUFFER, 0);
return;
}
// Mise à jour des données
memcpy((char*)vboAdress + offset, datas, sizeBytes);
// Annulation du pointeur
glUnmapBuffer(GL_ARRAY_BUFFER);
vboAdress = 0;
// Déverrouillage du VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void SpriteRect::render() {
glUseProgram(this->sShader->getProgramID());
glBindVertexArray(vaoId);
glUniformMatrix4fv(glGetUniformLocation(this->sShader->getProgramID(), "cameraMatrix"), 1, GL_FALSE, glm::value_ptr(this->cContainer->getCamera()->getCameraMatrix()));
glBindTexture(GL_TEXTURE_2D, this->tTexture->getId());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
glUseProgram(0);
}
Then when I comment out the [BlockObject]->render(); There is no more leak.
Actually the leak is about 30Kb/sec. I saw that when using updateVbo() method of SpriteRect there is a leak to.
Sorry comments are french but the code is easy ;)
Any ideas ?
For every new you do, there must be a corresponding delete. Your loop method does a lot of new into local variables, but no single delete.
Just trying to draw a point using glut and glew for opengl version 4.3
my code
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
is not rendering anything, can someone tell me what did i miss? here is full code:
#include <iostream>
using namespace std;
#include "vgl.h"
#include "LoadShaders.h"
enum VAO_IDs { Triangles, NumVAOS };
#define WIDTH 1024
#define HEIGHT 768
#define REFRESH_DELAY 10 //ms
//general
long frameCount = 0;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0, rotate_y = 0.0;
float translate_z = -3.0;
/////////////////////////////////////////////////////////////////////
//! Prototypes
/////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void timerEvent(int value)
{
glutPostRedisplay();
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount++);
}
void init (void)
{
// default initialization
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
// viewport
glViewport(0, 0, WIDTH, HEIGHT);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)WIDTH / (GLfloat)HEIGHT, 1, 10000.0);
}
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(WIDTH, HEIGHT);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("The Abyss");
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount);
if (glewInit()) //i guess this is true on failure
{
cerr << "Error initializing glew, Program aborted." << endl;
exit(EXIT_FAILURE);
}
//Init First
init();
//Init callback for Rendering
glutDisplayFunc(Renderer);
//Main Loop
glutMainLoop();
exit(EXIT_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
//!Mouse and keyboard functionality
////////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
switch (key)
{
case (27) :
exit(EXIT_SUCCESS);
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
You have requested a Core context. You need to:
Specify a vertex and fragment shader. There are no freebies in Core.
Stop using deprecated functionality like glBegin() and glMatrixMode().
Start using VBOs to submit your geometry.
Start using glDrawArrays() and friends to draw your geometry.
I would like to get color from the pixel in my game and save this color in variable. How to do it in opengl?
glReadPixels():
#include <GL/glut.h>
#include <iostream>
using namespace std;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10, 10, -10, 10, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glScalef(5,5,5);
glBegin(GL_TRIANGLES);
glColor3ub(255,0,0);
glVertex2f(-1,-1);
glColor3ub(0,255,0);
glVertex2f(1,-1);
glColor3ub(0,0,255);
glVertex2f(1,1);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void motion(int x, int y)
{
y = glutGet( GLUT_WINDOW_HEIGHT ) - y;
unsigned char pixel[4];
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
cout << "R: " << (int)pixel[0] << endl;
cout << "G: " << (int)pixel[1] << endl;
cout << "B: " << (int)pixel[2] << endl;
cout << endl;
}
int main(int argc, char **argv)
{
glutInitWindowSize(640,480);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("glReadPixels()");
glutDisplayFunc(display);
glutPassiveMotionFunc(motion);
glutMainLoop();
return 0;
}
struct{ GLubyte red, green, blue; } pixel;
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
#include <math.h>
#include <gl/glut.h>
struct Point {
GLint x;
GLint y;
};
struct Color {
GLfloat r;
GLfloat g;
GLfloat b;
};
void init() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(0.0, 0.0, 0.0);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 640, 0, 480);
}
//this function is used for getting color of pixel
Color getPixelColor(GLint x, GLint y) {
Color color;
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, &color);
return color;
}
void setPixelColor(GLint x, GLint y, Color color) {
glColor3f(color.r, color.g, color.b);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
glFlush();
}
void floodFill(GLint x, GLint y, Color oldColor, Color newColor) {
Color color;
color = getPixelColor(x, y);
if(color.r == oldColor.r && color.g == oldColor.g && color.b == oldColor.b)
{
setPixelColor(x, y, newColor);
floodFill(x+1, y, oldColor, newColor);
floodFill(x, y+1, oldColor, newColor);
floodFill(x-1, y, oldColor, newColor);
floodFill(x, y-1, oldColor, newColor);
}
return;
}
void onMouseClick(int button, int state, int x, int y)
{
Color newColor = {1.0f, 0.0f, 0.0f};
Color oldColor = {1.0f, 1.0f, 1.0f};
floodFill(320, 240, oldColor, newColor);
}
void draw_circle(Point pC, GLfloat radius) {
GLfloat step = 1/radius;
GLfloat x, y;
for(GLfloat theta = 0; theta <= 360; theta += step) {
x = pC.x + (radius * cos(theta));
y = pC.y + (radius * sin(theta));
glVertex2i(x, y);
}
}
void display(void) {
Point pt = {320, 240};
GLfloat radius = 50;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
draw_circle(pt, radius);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(200, 200);
glutCreateWindow("Open GL");
init();
glutDisplayFunc(display);
glutMouseFunc(onMouseClick);
glutMainLoop();
return 0;
}
This program builds with no problem, and the executable starts up, but no triangle shows up. I am following a GLSL tutorial where a Shader class is made to handle GLSL files.
Shader.h
#ifndef SHADER_H_
#define SHADER_H_
#include <GL/glew.h>
#include <GL/glfw.h>
#include <string>
class Shader {
public:
Shader();
Shader(const char *vsFile, const char *fsFile);
~Shader();
void init(const char *vsFile, const char *fsFile);
void bind();
void unbind();
unsigned int id();
private:
unsigned int shader_id;
unsigned int shader_vp;
unsigned int shader_fp;
};
#endif // SHADER_H_
Shader.cpp
#include "Shader.h"
#include <cstring>
#include <iostream>
#include <ftream>
#include <cstdlib>
using namespace std;
static char* textFileRead(const char *fileName) {
char* text;
if (fileName != NULL) {
FILE *file = fopen(fileName, "rt");
if (file != NULL) {
fseek(file, 0, SEEK_END);
int count = ftell(file);
rewind(file);
if (count > 0) {
text = (char*)malloc(sizeof(char) * (count + 1));
count = fread(text, sizeof(char), count, file);
text[count] = '\0';
}
fclose(file);
}
}
return text;
}
Shader::Shader() {}
Shader::Shader(const char *vsFile, const char *fsFile)
{
init(vsFile, fsFile);
}
void Shader::init(const char *vsFile, const char *fsFile)
{
shader_vp = glCreateShader(GL_VERTEX_SHADER);
shader_fp = glCreateShader(GL_FRAGMENT_SHADER);
const char *vsText = textFileRead(vsFile);
const char *fsText = textFileRead(fsFile);
if (vsText == NULL || fsText == NULL)
{
cerr << "Either vertex shader or fragment shader file is not found" << endl;
return;
}
glShaderSource(shader_vp, 1, &vsText, 0);
glShaderSource(shader_fp, 1, &fsText, 0);
glCompileShader(shader_vp);
glCompileShader(shader_fp);
shader_id = glCreateProgram();
glAttachShader(shader_id, shader_fp);
glAttachShader(shader_id, shader_vp);
glLinkProgram(shader_id);
}
Shader::~Shader()
{
glDetachShader(shader_id, shader_fp);
glDetachShader(shader_id, shader_vp);
glDeleteShader(shader_fp);
glDeleteShader(shader_vp);
glDeleteShader(shader_id);
}
unsigned int Shader::id()
{
return shader_id;
}
void Shader::bind()
{
glUseProgram(shader_id);
}
void Shader::unbind()
{
glUseProgram(0);
}
Main.cpp
#include "Shader.h"
#include <cstdlib>
#include <iostream>
using namespace std;
Shader shader;
void init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
shader.init("shader.vert", "shader.frag");
}
void resize(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
int main()
{
int running = GL_TRUE;
// init GLFW
if (!glfwInit())
exit(EXIT_FAILURE);
if (!glfwOpenWindow(300, 300, 0, 0, 0, 0, 0, 0, GLFW_WINDOW))
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetWindowTitle("ohhai.");
glfwSetWindowSizeCallback(resize);
/* CHECK GLEW */
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
cout << "Error: " << glewGetErrorString(err) << endl;
}
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
if (!GLEW_ARB_vertex_buffer_object)
{
cerr << "VBO not supported\n";
exit(1);
}
init();
while (running)
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glShadeModel(GL_SMOOTH);
shader.bind();
glBegin(GL_TRIANGLES);
//glColor3f(0.2f, 0.5f, 0.54f);
glVertex2f(0.0f, 0.5f);
//glColor3f(0.75f, 0.8f, 0.1f);
glVertex2f(-.5f, -.5f);
//glColor3f(0.0f, 0.9f, 0.2f);
glVertex2f(0.5f, -0.5f);
glEnd();
shader.unbind();
glfwSwapBuffers();
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
}
glfwTerminate();
exit(EXIT_SUCCESS);
}
shader.vert
void main()
{
// set the posistion of the current matrix
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
shader.frag
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Again, when this compiles under g++, it goes through fine, but no triangle was shown.
I haven't found the part where you setup the camera (modelview matrix) with gluLookAt or glTranslate/glRotate/glScale. So you use the default, corresponding to a camera at the origin and looking into -z, thus your triangle (which lies in the z=0 plane) is behind the near plane.