Setting Visual Studio Project with SDL and GLEW - c++

I'm new to using Visual Studio and the libraries OpenGL and SDL.
I'm having trouble setting up my program and keep running into errors when I try to build it.
Can anyone help me solve the following -
Error 1 error LNK2019: unresolved external symbol __imp__glewInit#0 referenced in function _SDL_main
Error 2 error LNK2019: unresolved external symbol __imp__glewGetErrorString#4 referenced in function _SDL_main
Error 3 error LNK2001: unresolved external symbol __imp____GLEW_VERSION_3_0
Error 4 error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
Error 5 error LNK1120: 4 unresolved externals
6 IntelliSense: identifier "GLuint" is undefined
7 IntelliSense: identifier "GLuint" is undefined
This is my code -
main.c
#include<SDL.h>
#include<GL\glew.h>
#include <stdio.h>
char shouldExit = 0;
int main(void)
{
/* Initialize SDL *l
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
return 1;
}
/* Create the window, OpenGL context */
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow(
"TestSDL",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480,
SDL_WINDOW_OPENGL);
if (!window) {
fprintf(stderr, "Could not create window.ErrorCode = %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_GL_CreateContext(window);
/* Make sure we have a recent version of OpenGL */
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
fprintf(stderr, "Could not initialize glew.ErrorCode = %s\n", glewGetErrorString(glewError));
SDL_Quit();
return 1;
}
if (!GLEW_VERSION_3_0) {
fprintf(stderr, "OpenGL max supported version is too low.\n");
SDL_Quit();
return 1;
}
/* Setup OpenGL state */
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glOrtho(0, 640, 480, 0, 0, 100);
glEnable(GL_TEXTURE_2D);
/* The game loop */
while (!shouldExit) {
// Handle OS message pump
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
shouldExit = 1;
}
}
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
/* Game logic goes here */
SDL_GL_SwapWindow(window);
}
SDL_Quit();
return 0;
}
DrawUtils.c
/***********************************************************************
Utilities for loading and drawing sprites.
*/
#include<GL/glew.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
/* Load a file into an OpenGL texture, and return that texture. */
GLuint glTexImageTGAFile( const char* filename, int* outWidth, int* outHeight )
{
const int BPP = 4;
/* open the file */
FILE* file = fopen( filename, "rb" );
if( file == NULL ) {
fprintf( stderr, "File: %s -- Could not open for reading.\n", filename );
return 0;
}
/* skip first two bytes of data we don't need */
fseek( file, 2, SEEK_CUR );
/* read in the image type. For our purposes the image type should
* be either a 2 or a 3. */
unsigned char imageTypeCode;
fread( &imageTypeCode, 1, 1, file );
if( imageTypeCode != 2 && imageTypeCode != 3 ) {
fclose( file );
fprintf( stderr, "File: %s -- Unsupported TGA type: %d\n", filename, imageTypeCode );
return 0;
}
/* skip 9 bytes of data we don't need */
fseek( file, 9, SEEK_CUR );
/* read image dimensions */
int imageWidth = 0;
int imageHeight = 0;
int bitCount = 0;
fread( &imageWidth, sizeof( short ), 1, file );
fread( &imageHeight, sizeof( short ), 1, file );
fread( &bitCount, sizeof( unsigned char ), 1, file );
fseek( file, 1, SEEK_CUR );
/* allocate memory for image data and read it in */
unsigned char* bytes = (unsigned char*)calloc( imageWidth * imageHeight * BPP, 1 );
/* read in data */
if( bitCount == 32 ) {
int it;
for( it = 0; it != imageWidth * imageHeight; ++it ) {
bytes[ it * BPP + 0 ] = fgetc( file );
bytes[ it * BPP + 1 ] = fgetc( file );
bytes[ it * BPP + 2 ] = fgetc( file );
bytes[ it * BPP + 3 ] = fgetc( file );
}
} else {
int it;
for( it = 0; it != imageWidth * imageHeight; ++it ) {
bytes[ it * BPP + 0 ] = fgetc( file );
bytes[ it * BPP + 1 ] = fgetc( file );
bytes[ it * BPP + 2 ] = fgetc( file );
bytes[ it * BPP + 3 ] = 255;
}
}
fclose( file );
/* load into OpenGL */
GLuint tex;
glGenTextures( 1, &tex );
glBindTexture( GL_TEXTURE_2D, tex );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0,
GL_BGRA, GL_UNSIGNED_BYTE, bytes );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
free( bytes );
if( outWidth ) {
*outWidth = imageWidth;
}
if( outHeight ) {
*outHeight = imageHeight;
}
return tex;
}
/* Draw the sprite */
void glDrawSprite( GLuint tex, int x, int y, int w, int h )
{
glBindTexture( GL_TEXTURE_2D, tex );
glBegin( GL_QUADS );
{
glColor3ub( 255, 255, 255 );
glTexCoord2f( 0, 1 );
glVertex2i( x, y );
glTexCoord2f( 1, 1 );
glVertex2i( x + w, y );
glTexCoord2f( 1, 0 );
glVertex2i( x + w, y + h );
glTexCoord2f( 0, 0 );
glVertex2i( x, y + h );
}
glEnd();
}
DrawUtils.h
#ifndef DRAWUTILS_H
#define DRAWUTILS_H
#ifdef __cplusplus
extern "C" {
#endif
GLuint glTexImageTGAFile( const char* filename, int* outWidth, int* outHeight );
void glDrawSprite( GLuint tex, int x, int y, int w, int h );
#ifdef __cplusplus
}
#endif
#endif
Am I missing an #include?

No, you're missing a library. You're including the GLEW header file(s):
#include<GL\glew.h>
However, header files only define the function prototypes (such as glewInit()) - the actual implementations of those functions will be stored in a .lib (or .a) file, which you must link with in order to build your project.
It's been a while since I used Visual Studio, but I'd think that you would normally set up linker options as part of your project configuration. However, it is possible to specify linker options within your code, if you must:
#pragma comment(lib, "glew/glew32s.lib")
Note that the #pragma method is MSVC-specific and probably won't work on other compilers.
If you can't be bothered fiddling around with linker options, you could always just add glew.c to your project instead.
One other thing: You're using GLuint in DrawUtils.h without including either gl.h or glew.h:
GLuint glTexImageTGAFile( const char* filename, int* outWidth, int* outHeight );
void glDrawSprite( GLuint tex, int x, int y, int w, int h );

Regarding Visual Studio 2017, OpenGL, SDL2 and GLEW, I recommend this webpage.
I copy and paste text only.
Part A - Downloading SDL and GLEW
A1 Create a folder OpenGL. In directory (disk) C:, create (by right click > New > Folder) a new folder with name OpenGL.
A2 Download the SDL2-devel-2.0.8-VC.zip (Visual C++ 32/64-bit). It can be found at https://www.libsdl.org/download-2.0.php. Scroll to the bottom of the page and find Development Libraries.
A2a Download the version for Visual C++. It is the SDL2-devel-2.0.8-VC.zip (Visual C++ 32/64-bit). Navigate (always by double click) to C: > OpenGL.
A2b Drag (or, by right click, copy and paste) folder SDL2-2.0.8 from the window where it is downloaded, into folder OpenGL.
A2c If the folder SDL2-devel-2.0.8-VC is downloaded, double click it to get SDL2-2.0.8.
A3 Download the GLEW. At http://glew.sourceforge.net/ below Downloads click Windows 32-bit and 64-bit. Navigate to C: > OpenGL. Drag (or, by right click, copy and paste) folder glew-2.1.0 from the window where it is downloaded, into folder *OpenGL.
A3a If folder glew-2.1.0-win32 is downloaded, double click it for get glew-2.1.0.
Part B - Creating a Visual Studio Project
B1 Create an empty project.
B1a At the Visual Studio main menu, click File. Then go to New > Project…
B1b In the left part of the New Project window, click Visual C++ if it is not clicked.
B1c In the center of the screen click Empty Project.
B1d Below that, find the Name text box, type Project-0.
B1e Next to Location text box, click Browse... and navigate to C: > OpenGL.
B1f Click Select a folder. The Location in New Project window is C:\OpenGL.
B1g Make sure the Create directory for solution box is not checked.
B1h Click OK.
B2 Add your source file to the Project.
B2a In the Solution Explorer window (at the left side of the screen), right click the Source Files folder (the last one).
B2b Click Add > New Item…
B2c In the Add New Item - Project-0 window, click C++ File (.cpp) (the first one) from the middle of the window. In Name text box type Main.cpp.
B2d. The Location is C:\OpenGL\Project-0.
B2e Click the Add button. The file will open in the main text editor but leave the file blank for now.
Part C - Installing SDL and GLEW on a Project
C1 Add the Include folders.
C1a Configure the Additional Include Directories: In Solution Explorer right click on the name of your project, that is Project-0, and select Properties.
C1b Add SDL's include folder: Open the C/C++ drop-down menu. Click General > Additional Include Directories > down arrow at the right of the field > Edit in the drop down menu.
C1c In Additional Include Directories, click the first icon > copy and paste, C:\OpenGL\SDL2-2.0.8\include
C1d Add GLEW's include folder: Click again the first icon > copy and paste: C:\OpenGL\glew-2.1.0\include Click OK on Additional Include Directories window.
C2 Add the x86 and Win32 folders.
C2a Configure the linker Additional Library Directories: Open the Linker drop-down menu, and click General.
C2b Add the x86 folder: Click Additional Library Directories entry, and click the down arrow at the right of the field. Click Edit in the drop-down menu.
C2c In Additional Library Directories click the first icon > copy and paste, C:\OpenGL\SDL2-2.0.8\lib\x86
C2d Add the Win32 folder: Click the first icon > copy and paste, C:\OpenGL\glew-2.1.0\lib\Release\Win32 Click OK.
C3 Add the four library files.
C3a Configure the linker Additional Dependencies: In the Linker drop-down menu, click Input. Click the Additional Dependencies entry > the down arrow at the right of the field > Edit in the drop-down menu.
C3b On the top-most text box of the Additional Dependencies window, copy and paste, SDL2.lib; SDL2main.lib; glew32.lib; opengl32.lib Click OK in the Additional Dependencies window.
C4 Configure the linker subsystem to console.
C4a In the Linker drop-down menu, click System > SubSystem. Click the down arrw and select Console(/SUBSYSTEM:CONSOLE) from the dropdown menu. Click Apply, then OK on the Project Property Pages window.
C5 Copy SDL2.dll file from x86 folder, and paste to Project-0 folder.
C5a Navigate to C: > OpenGL > SDL2-2.0.8 > lib > x86. Inside x86 folder click SDL2.dll file > right-click > Copy.
C5b Navigate to C: > OpenGL > Project-0. Right-click an empty area in Project-0 folder, and select Paste.
C5c The SDL2.dll file should now be in your project directory along with your Main.cpp file and a few other files created by Visual Studio.
C6 Copy the glew32.dll file from Win32 and paste to Project folder.
C6a Navigate to C: > OpenGL > glew-2.1.0 > bin > Release > Win32. Click glew32.dll > right-click > Copy.
C6b Navigate to C: > OpenGL > Project-0. Right-click an empty area in Project-0 folder, and select Paste.
C6c The glew32.dll file should now be in Project-0 folder along with Main.cpp, SDL2.dll, and a few other files created by Visual Studio.
Part D - Testing and Debugging Your Project
D1 Download the code: Click http://lazyfoo.net/tutorials/SDL/51_SDL_and_modern_opengl/index.php > Scroll down and find Download the media and source code for this tutorial here. Click here and download 51_SDL_and_modern_opengl.cpp folder. Double click it > double click file of same name. Its code will appear in Visual Studio by the side of Main.cpp file. Copy the code (413 lines) and paste on Main.cpp code area. On V.S. main menu click the green arrow Local Windows Debugger and wait... If everything went well two windows appear: one black and one with title: SDL Tutorial and inside a white square with black background. If there is any problem try fix the error(s). If you fail, repeat above steps.
Part E - Creating a Project with OpenGL-SDL-GLEW Template in Visual Studio 2017
E1 Create a project template: Go to Visual Studio main menu and, while Project-0 is open, click Project > Export Template.... On Export template Wizard check Project Template, if it's not checked. Click Next >. On Select Template Options, in Template name text box type: OpenGL-SDL-GLEW. Click Finish. Template has been created.
E2 Create OpenGL-SDL-GLEW project with created Template
E2a On V.S. main menu click File > New > Project.... On the New Project window, click template: OpenGL-SDL-GLEW. In Name text field, type: Project-1. Be sure Create directory for solution is unchecked. Click OK.
E2b On Solution Explorer, double click Source Files. Click Main.cpp > right click > click Exclude From Project.
E2c Right click Source Files > Add > New Item.... On Add New Item - Project-1 window, click C++ File (.cpp). In Name: text box type: Main.cpp. The Location should be C:\OpenGL\Project-1. Click Add. Now on Solution Explore, below Source Files, you have the new Main.cpp file.
E3 Add SDL2.dll file to project-folder
E3a Navigate to C: > OpenGL > Project-0 > click file SDL2.dll > right click > click Copy.
E3b Navigate to C: > OpenGL > Project-1 > click on empty area > right click > click Paste.
E3c Now file SDL2.dll is in folder Project-1 among Main.cpp and other 4 files.
E4 Add glew32.dll file to project-folder
E4a Navigate to C: > OpenGL > Project-0 > click file glew32.dll > right click > click Copy.
E4b Navigate to C: > OpenGL > Project-1 > click on empty area > right click > click Paste.
E4c Now file glew32.dll is in folder Project-1 among SDL2.dll, Main.cpp and other 4 files.
E5 Test your project as above. Good job.
Tip
Remember the 3 extra steps you have to take: Creating project with OpenGL-SDL-GLEW Template in Visual Studio 2017 is like creating an ordinary C++ project, but with three more steps:
1 In Solution Explorer, Source Files, the source file (Main.cpp in the example above) of the template project (Project-0, in the example) should be excluded from new project (Project-1 in example).
2 The file SDL2.dll should be copied from a previous project and pasted into new project.
3 The file glew32.dll should be copied from a previous project and pasted into new project.

Related

Failed to load font in SFML C++ on other computers

I am making an SFML project using Visual Studio, and I have an error when sharing it with other people (works fine on my computer).
Basically they get the error
Failed to load font "../fonts/BalooPaaji2.ttf" (failed to create the font face)
So I tried to uninstall the font in my OS fonts and only keep it in the project itself, and everything still works fine for me.
I though it was maybe a directory problem but if so why would the .exe file work fine for me and not other people ?
Here is the code of my write function:
void write(sf::RenderWindow& window, std::string t1, sf::IntRect rect) {
//load font
sf::Font font;
font.loadFromFile("../fonts/BalooPaaji2.ttf");
//create the text element
sf::Text text(t1, font);
text.setStyle(sf::Text::Bold);
text.setFillColor(sf::Color(0,0,0,150));
//size and place the text element according to the space available, this is specific of my project (and probably could be optimized) so you can skip this part
text.setCharacterSize(rect.height/2);
sf::FloatRect textRect = text.getLocalBounds();
text.setOrigin(textRect.left + textRect.width / 2.0f, textRect.top + textRect.height / 2.0f);
text.setPosition(sf::Vector2f(rect.left + rect.width/2, rect.top + rect.height / 2));
if (t1 == "Play") {
text.setPosition(sf::Vector2f(rect.left + rect.width / 2, rect.top + rect.height / 1.8));
}
window.draw(text);
}
My structure looks like that:
I don't have any clues of where this problem could come from, any help will be appreciated and feel free to ask for more information you could need.

How to not include texture in exe folder

I'm doing some sfml project for school and teacher wants only the .exe program. I'm using Visual Studio 2017. In this project I'm using texture from .jpg file
sf::RenderWindow window(sf::VideoMode(640, 480, 32), "Kurs SFML ");
sf::Texture texture;
texture.loadFromFile("wood.jpg");
sf::Sprite pic;
pic.setTexture(texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(pic);
window.display();
This file ( wood.jpg ) needs to be to in the same folder as project to show this texture otherwise it only shows black screen. When I checked the .exe program which is in another folder, it also needs this file to be in this folder or .exe shows black screen. But my teacher wants only .exe file without any folders. So is it possible to do something to not include this file( wood.jpg ) but show the texture in the .exe ?
Embed your texture in your executable.
One easy solution is to write a small tool that reads the file and writes out a C++ source file with a constexpr std::array containing the raw bytes. Then load your texture from that variable (SFML has functions to load a resource from memory) that you link into your executable.
Writing such a tool shouldn't be more than 10-20 lines of code.
For a SFML specific solution you can do this.
sf::Image tmp;
tmp.loadFromFile("super.jpeg");
std::ofstream file;
file.open("textarray.cpp");
size_t psize = tmp.getSize().x * tmp.getSize().y * 4;
auto ptr = tmp.getPixelsPtr();
file << "sf::Uint8 imageArray[] = {" << (int)ptr[0];
for (size_t i = 1; i<psize; ++i)
file << "," << (int)ptr[i];
file << "};";
file.close();
This will create a file name textarray.cpp containing something that looks like sf::Uint8 imageArray[] = {...};
Then you can load it in your program like this.
sf::Uint8 imageArray[] = {...};
sf::Image img;
img.create(80, 80, imageArray); // Replace 80, 80 with width and height of your image!!!
sf::Texture texture;
texture.loadFromImage(img);
sf::Sprite sprite;
sprite.setTexture(texture);
From here, just draw the sprite like normal.

SDL2 does not draw image using texture

I have been attempting to get a simple SDL2 program up to display an image and then exit. I have this code:
/* compile with `gcc -lSDL2 -o main main.c` */
#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>
int main(void){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, 0);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);
SDL_Surface * s = SDL_LoadBMP("../test.bmp");
SDL_Texture * t = SDL_CreateTextureFromSurface(r, s);
SDL_FreeSurface(s);
SDL_RenderClear(r);
SDL_RenderCopy(r, t, 0, 0);
SDL_RenderPresent(r);
SDL_Delay(2000);
SDL_DestroyTexture(t);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);
SDL_Quit();
}
I am aware that I have omitted the normal checks that each function succeeds - they all do succeed, they were removed for ease of reading. I am also aware I have used 0 rather than null pointers or the correct enum values, this also is not the cause of the issue (as the same issue occurs when I correctly structure the program, this was a quick test case drawn up to test the simplest case)
The intention is that a window appear and shows the image (which is definitely at that directory), wait for a couple of seconds and exit. The result, however, is that the window appears correctly but the window is filled with black.
An extra note SDL_ShowSimpleMessageBox() appears to work correctly. I don't know how this relates to the rest of the framework though.
I'll just clear this, you wanted to make a texture, do it directly to ease control, plus this gives you better control over the image, try using this code, fully tested, and working, all you wanted was for the window to show the image and close within 2 seconds right?. If the image doesn't load then it's your image's location.
/* compile with `gcc -lSDL2 -o main main.c` */
#include <SDL.h>
#include <SDL_image.h>
#include <iostream> //I included it since I used cout
int main(int argc, char* argv[]){
bool off = false;
int time;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture * s = NULL;
s = IMG_LoadTexture(r, "../test.bmp"); // LOADS A TEXTURE DIRECTLY FROM THE IMAGE
if (s == NULL)
{
cout << "FAILED TO FIND THE IMAGE" << endl; //we did this to check if IMG_LoadTexture found the image, if it showed this message in the cmd window (the black system-like one) then it means that the image can't be found
}
SDL_Rect s_rect; // CREATES THE IMAGE'S SPECS
s_rect.x = 100; // just like the window, the x and y values determine it's displacement from the origin which is the top left of your window
s_rect.y = 100;
s_rect.w = 640; //width of the texture
s_rect.h = 480; // height of the texture
time = SDL_GetTicks(); //Gets the current time
while (time + 2000 < SDL_GetTicks()) //adds 2 seconds to the past time you got and waits for the present time to surpass that
{
SDL_RenderClear(r);
SDL_RenderCopy(r, s, NULL, &s_rect); // THE NULL IS THE AREA YOU COULD USE TO CROP THE IMAGE
SDL_RenderPresent(r);
}
SDL_DestroyTexture(s);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);
return 0; //returns 0, closes the program.
}
if you wanted to see a close button on the window and want it to take effect then create an event then add it to the while area to check if it's equal to SDL_Quit();, I didn't include it since you wanted it to immediately close within 2 seconds, thus, rendering the close button useless.
HAPPY CODING :D
When using SDL_RENDERER_SOFTWARE for the renderer flags this worked. Also it worked on a different machine. Guess there must be something screwed up with my configuration, although I'm not sure what it is because I'm still getting no errors shown. Ah well, mark as solved.
I believe this to be (not 100% sure, but fairly sure), due to this line of code:
SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);
According to the SDL wiki article SDL_CreateRenderer, the parameters required for the arguments that you are passing in are as follows:
SDL_Window* window
int index
Uint32 flags
You are passing in the pointer to the window correctly, as well as the index correctly, but the lack of a flag signifies to SDL that SDL should use the default renderer.
Most systems have a default setting for applications for which renderer should be used, and this can be modified on a application by application basis. If no default setting is provided for a specific application, the render look up immediately checks the default render settings list. The SDL wiki briefly refers to this list by the following line at the bottom of the remarks section:
"Note that providing no flags gives priority to available SDL_RENDERER_ACCELERATED renderers."
What's not explained here in the wiki is that the "renderers" the wiki is referring to comes from the default renderer list.
This leads me to believe that you have either changed a setting somewhere in the course of history of your computer, or elsewhere in you visual studio settings that is resulting in no list to be found. Therefore you must explicitly inform SDL which renderer to use because of your machine settings. Otherwise using an argument of 0 should work just fine. In the end this doesn't hurt as it's better to be explicit in your code rather than implicit if at all possible.
(That said, all of my deductions are based off of the fact that I am assuming that everything you said that works, works. If this is not true, then the issue could be because of a vast variety of reasons due to the lack of error checking.)

GLFW: Compilation errors C++ [duplicate]

I am having some difficulties with codeblocks 10.05 recognizing the GLFW libraries on my machine. When I create an empty project, and copy paste this code found from this GLFW tutorial >> http://content.gpwiki.org/index.php/GLFW:Tutorials:Basics
#include <stdlib.h>
#include <GL/glfw.h>
void Init(void);
void Shut_Down(int return_code);
void Main_Loop(void);
void Draw_Square(float red, float green, float blue);
void Draw(void);
float rotate_y = 0,
rotate_z = 0;
const float rotations_per_tick = .2;
int main(void)
{
Init();
Main_Loop();
Shut_Down(0);
}
void Init(void)
{
const int window_width = 800,
window_height = 600;
if (glfwInit() != GL_TRUE)
Shut_Down(1);
// 800 x 600, 16 bit color, no depth, alpha or stencil buffers, windowed
if (glfwOpenWindow(window_width, window_height, 5, 6, 5,
0, 0, 0, GLFW_WINDOW) != GL_TRUE)
Shut_Down(1);
glfwSetWindowTitle("The GLFW Window");
// set the projection matrix to a normal frustum with a max depth of 50
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect_ratio = ((float)window_height) / window_width;
glFrustum(.5, -.5, -.5 * aspect_ratio, .5 * aspect_ratio, 1, 50);
glMatrixMode(GL_MODELVIEW);
}
void Shut_Down(int return_code)
{
glfwTerminate();
exit(return_code);
}
void Main_Loop(void)
{
// the time of the previous frame
double old_time = glfwGetTime();
// this just loops as long as the program runs
while(1)
{
// calculate time elapsed, and the amount by which stuff rotates
double current_time = glfwGetTime(),
delta_rotate = (current_time - old_time) * rotations_per_tick * 360;
old_time = current_time;
// escape to quit, arrow keys to rotate view
if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS)
break;
if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS)
rotate_y += delta_rotate;
if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS)
rotate_y -= delta_rotate;
// z axis always rotates
rotate_z += delta_rotate;
// clear the buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw the figure
Draw();
// swap back and front buffers
glfwSwapBuffers();
}
}
void Draw_Square(float red, float green, float blue)
{
// Draws a square with a gradient color at coordinates 0, 10
glBegin(GL_QUADS);
{
glColor3f(red, green, blue);
glVertex2i(1, 11);
glColor3f(red * .8, green * .8, blue * .8);
glVertex2i(-1, 11);
glColor3f(red * .5, green * .5, blue * .5);
glVertex2i(-1, 9);
glColor3f(red * .8, green * .8, blue * .8);
glVertex2i(1, 9);
}
glEnd();
}
void Draw(void)
{
// reset view matrix
glLoadIdentity();
// move view back a bit
glTranslatef(0, 0, -30);
// apply the current rotation
glRotatef(rotate_y, 0, 1, 0);
glRotatef(rotate_z, 0, 0, 1);
// by repeatedly rotating the view matrix during drawing, the
// squares end up in a circle
int i = 0, squares = 15;
float red = 0, blue = 1;
for (; i < squares; ++i){
glRotatef(360.0/squares, 0, 0, 1);
// colors change for each square
red += 1.0/12;
blue -= 1.0/12;
Draw_Square(red, .6, blue);
}
}
and compile it using codeblocks it returns me this error:
/home/user/Graphics/Project_2/test.c|27|undefined reference to `glfwInit'|
/home/user/Graphics/Project_2/test.c|30|undefined reference to `glfwOpenWindow'|
......
.....
....
...
but when I create a simple *.c file and compile it with :
gcc myprog.c -o myprog -lglfw -lGL -lpthread
it works.. How can I make codeblocks work with GLFW??
thanks
Follow the following procedure.
First download the GLFW from here.
unzip the zip file
copy the glfw.h file from the include folder and paste to the folder "C:\Program Files\CodeBlocks\MinGW\include\GL"
copy all file (libglfw.a and libglfwdll.a ) from the lib_mingw folder
and paste to the folder "C:\Program Files\CodeBlocks\MinGW\lib"
glfw.dll file from the lib_mingw folder of unzip file and paste it
inside "C:\Windows\System32" floder. If you don't like to keep it in system32 then you can keep it with your project exe file.
Now while creating the GLFW project in code::blocks give the path C:\Program Files\CodeBlocks\MinGW" for glfw location
IF you are again confuse then go here for step by step procedure with image of every step.
Make sure that you have the correct type of glfw libs. ie x86 or x64 for your mingw compiler. 8 Hours of time searching for undefined reference errors ie linker problems to glfw.
Follow these instrucions:
http://codeincodeblock.blogspot.com/2011/02/setup-glfw-project-in-codeblock.html
I was having similar problems earlier with importing GLFW into codeblocks, and I recently found something that works for me.
I can see that you have already done the header installation correctly, but I will include that in this response so that you can double-check that everything is in tip-top condition.
I also recommend that you use the sample code within the 'Documentation' tab of glfw.org. It works really well for me, so I think it might for you as well.
Since you are using GLFW, I will assume that you want to use OpenGL in your application, so I will include the installation of OpenGL in the tutorial
A. Creating relevant folders
The first thing you will need to do is set up a location for library files and header files on your system. You can either creates these folders within a specified location on your drive, or you can create these folders within your code::blocks project.
In my case, I created a 'lib' and 'head' folder in my code::blocks project folder.
B. Downloading & Installing necessary media
GLFW:
Head over to GLFW.org, and hit 'Downloads'.
Click '32-bit Windows binaries', and open the 'glfw-version.bin.WIN32' within zip file that was downloaded.
Open the 'include' folder and copy the enclosed GLFW folder to the 'head' folder you created in part A.
Open up 'glfw-version.bin.WIN32' again, and pick the 'lib' folder that corresponds to your compiler. Because I am using the MinGW GCC compiler, I picked 'lib-mingw'. To find your compiler, go to code::blocks, click settings, and then click 'compiler...'. Your compiler is found in the 'selected compiler' section of the window that appears.
Once you've found the 'lib' folder that you will use, open it, and copy all of the files within into the 'lib' folder that you created during part A.
GLEW (OpenGL):
Go to this link
Open the folder that is within the downloaded zip.
Go to 'lib', then release, then Win32, and copy all of the files located there into the 'lib' folder you created in step A.
Go back to the folder within the downloaded zip.
Enter the 'include' directory, and copy the 'GL' folder into the 'head' folder created in part a.
At this point, your 'head' folder should contain 'GLFW' and 'GL' folders, and your 'lib' folder should contain 'glew32', 'glew32s', and all of the library files from GLFW for your compiler.
C. Configuring your code::blocks project
Once you've opened your project, right click on the name of your project in your workspace, and hit 'build options...
On the left of the window that has appeared, make sure 'Debug' is selected.
Next click the 'linker settings' tab, and add the following libraries: 'glfw.3', 'gdi32', and 'opengl32'.
Next, in the 'Search Directories' tab, select the 'Compiler' tab.
Add the path to your 'head' folder. If the head folder was created within your project folder, you can just type 'head'
Also in the 'Search Directories' tab, select the 'Linker' tab.
Add the path to your 'lib' folder. Again, if the lib folder was created withing your project folder, you can just type 'lib'.
Hit 'OK' at the bottom of the window.
D. Build and Run your code :)! Hope this helps!

GLFW get screen height/width?

Playing around with OpenGL for a while, using the freeglut library, I decided that I will use GLFW for my next training project instead, since I was told that GLUT was only designed for learning purposes and should not be used professionally. I had no problems with linking the lib to my NetBeans project and it compiles just fine, using mingw32 4.6.2.
However, I am running into difficulties trying to position the window at the center of the screen.
Under freeglut, I previously used:
glutInitWindowPosition (
(glutGet(GLUT_SCREEN_WIDTH)-RES_X) / 2,
(glutGet(GLUT_SCREEN_HEIGHT)-RES_Y) / 2
);
I can't find any glfw function that would return the screen size or width. Is such a function simply not implemented?
How about glfwGetDesktopMode, I think this is what you want.
Example:
GLFWvidmode return_struct;
glfwGetDesktopMode( &return_struct );
int height = return_struct.Height;
For GLFW they use glfwGetVideoMode, which has a different call but the return structure can be used in the same way.
first you need two variables to store your width and height.
int width, height;
then as described on page 14 of the reference.
glfwSetWindowPos(width / 2, height / 2);
and as a bonus you can then call
glfwGetWindowSize(&width, &height);
this a void function and does not return any value however it will update the two previously declared variables.. so place it in the mainloop or the window reshape callback function.
you can verify this in the official manual here on page 15.
This might help somebody...
void Window::CenterTheWindow(){
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwSetWindowPos(m_Window, (mode->width - m_Width) / 2, (mode->height - m_Height) / 2);
}
m_Width and m_Height are variables that have the width and the height of the window.
Reference: http://www.glfw.org/docs/latest/monitor.html