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.
I have an interesting bug that has been "bugging" me for a few days now.
I am currently using OpenGL to draw text on a screen. I am utilizing the OGLFT library to assist the drawing. This library actually uses the freetype2 library. I am actually not doing anything special with the text. I am only looking for monochromatic text.
Anyways, after implementing the library, I noticed that the text is only drawn correct when I have glStipple enabled. I believe that there is some interference issue between the OGLFT library and what I am enabling.
I was wondering if there is anyone out there with some experience on using the OGLFT library. I am posting a minimalist example of my code to demonstrate what is going on:
(Please note that there are some variables that are used to st the zoom factor of my glCanvas and the position of the camera and that this is only for 2D)
double _zoomX = 1.0;
double _zoomY = 1.0;
double _cameraX = 0;
double _cameraY = 0;
/* This function gets called everytime a draw routine is needed */
void modelDefinition::onPaintCanvas(wxPaintEvent &event)
{
wxGLCanvas::SetCurrent(*_geometryContext);// This will make sure the the openGL commands are routed to the wxGLCanvas object
wxPaintDC dc(this);// This is required for drawing
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
updateProjection();
OGLFT::Monochrome *testface = new OGLFT::Monochrome( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
testface->draw(0, 0, "test");
glEnable(GL_LINE_STIPPLE);// WHen I comment out this line, the text is unable to be drawn
glLineStipple(1, 0b0001100011000110);
glBegin(GL_LINES);
glVertex2d(_startPoint.x, _startPoint.y);
glVertex2d(_endPoint.x, _endPoint.y);
glEnd();
glDisable(GL_LINE_STIPPLE);
SwapBuffers();
}
void modelDefinition::updateProjection()
{
// First, load the projection matrix and reset the view to a default view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-_zoomX, _zoomX, -_zoomY, _zoomY, -1.0, 1.0);
//Reset to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, (double)this->GetSize().GetWidth(), (double)this->GetSize().GetHeight());
/* This section will handle the translation (panning) and scaled (zooming).
* Needs to be called each time a draw occurs in order to update the placement of all the components */
if(_zoomX < 1e-9 || _zoomY < 1e-9)
{
_zoomX = 1e-9;
_zoomY = _zoomX;
}
if(_zoomX > 1e6 || _zoomY > 1e6)
{
_zoomX = 1e6;
_zoomY = _zoomX;
}
glTranslated(-_cameraX, -_cameraY, 0.0);
}
Also one thing to note is that the code below the glEnable(GL_LINE_STIPPLE); is required. It is as if the glStipple needs to be drawn correctly for the text to be displayed correctly.
Looking through your code, I believe that your intention is to render it as a greyscale? If so, then you can simply use the OGLFT::Grayscale *testface = new OGLFT::Grayscale( "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 8);
This will get what you need without having to worry about the issue that you posted. In fact, I recommend doing it this way too.
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.
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
I have a couple of queries regarding programming in DirectX using C++.
The first problem that I am having is that I have a texture that doesn't display on screen properly. The window is set to 800x600 when it is created and the texture is also 800x600 but when the program is loaded, only part of the texture is displayed. The code is shown below for the texture loading and drawing.
//This sets the image
helpFileTexture = new Texture(d3dDevice, L"../Resources/Help Guide.png");
//This is the draw function
helpFileTexture->Draw(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
//Which calls this
void Texture::Draw(long xPos, long yPos, long width, long height)
{
sprite->Begin(NULL);
RECT imageRectangle;
imageRectangle.left = xPos;
imageRectangle.top = yPos;
imageRectangle.right = imageRectangle.left + width;
imageRectangle.bottom = imageRectangle.top + height;
sprite->Draw(texture, &imageRectangle, &D3DXVECTOR3(1.0f, 1.0f, 0.0f), &D3DXVECTOR3((float)xPos, (float)yPos, 0.0f), D3DCOLOR_XRGB(255, 255, 255));
sprite->End();
}
As I said the SCREEN_WIDTH is set to 800 and the SCREEN_HEIGHT is set to 600 (which are also the same dimensions as the image). It draws from the top left as it should do but will only show part of the image. The window size was set to about 1100x1100 when the entire image could be seen. Have I done something wrong in the coding to set the image size.
The next thing is that I am having a problem hiding the cursor. I want to hide the cursor when I click the left mouse button and then have it reappear when I let go. But the cursor does not disappear. The coding for this is below.
if(input->mouseButtons.rgbButtons[0])
{
d3dDevice->ShowCursor(FALSE);
GetCursorPos(&input->mousePosition);
SetCursorPos(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
input->mousePosition.x -= SCREEN_WIDTH / 2;
mainCamera->UpdateYaw(input->mousePosition.x * rotationSpeed);
indexYaw += mainCamera->GetYaw();
D3DXMatrixRotationY(&viewMatrix, indexYaw);
d3dDevice->SetTransform(D3DTS_VIEW, &viewMatrix);
}
else
{
d3dDevice->ShowCursor(TRUE);
}
As you can see the cursor is suppose to disappear when the left mouse button is click for the camera control but it still shows.
The last couple of things is what is the best way to implement collision detection between objects and terrain following or can you link me to where a good place to find these would be.
I know this is a lot I have asked but any help would be great
The fix you implemented is not correct (the scaling one). The reason for the sizing issue is that when the texture is loaded using the D3DXLoadTextureFromFile method, DirectX changes the size of the image to the nearest power of 2 higher than the actual size. Hence the reason for it appearing larger than the screen.
So, in order to prevent it from doing this, you should use the D3DXLoadTextureFromFileEx method, and specify D3DX_DEFAULT_NONPOW2 for parameters 3 and 4. This will stop DirectX from scaling up the size of the texture. For more information on the method, refer to the MSDN page: http://msdn.microsoft.com/en-us/library/bb172802(v=vs.85).aspx
Note: Be sure to use D3DPOOL_MANAGED as the D3DPOOL option, otherwise if you use D3DPOOL_DEFAULT your models will become see through! (as I found out).