tags:

views:

110

answers:

2

I'm trying to render text to the screen but keep getting garbage symbols and i can't figure out what is so different in my approach.

This code will work in my main program:

char vectorText[80];
sprintf(vectorText, "vector%i = [%f, %f, %f]", 1, vector[0]->x, vector[0]->y, vector[0]->z);
char* newText =  vectorText;
Text* finalText = NULL;
finalText = new Text(22, 0, 400, false, newText, 0.0f, 0.0f, 1024.0f, 200.0f);
scene.AddText(finalText);

However, as soon as i place it inside a function it starts spitting out garbage. I know it's the char vectorText[] because when i bypass it then i get text.

char vectorText[80] = "This prints garbage";
//sprintf(vectorText, "vector%i = [%f, %f, %f]", 1, vector[0]->x, vector[0]->y, vector[0]->z);
//char* newText =  vectorText;
Text* finalText = NULL;
finalText = new Text(22, 0, 400, false, vectorText, 0.0f, 0.0f,  1024.0f, 200.0f);
scene.AddText(finalText);

The bottom one works, but obviously it's not going to give me what i need.

//char vectorText[80];
//sprintf(vectorText, "vector%i = [%f, %f, %f]", 1, vector[0]->x, vector[0]->y, vector[0]->z);
char* newText =  "Text will work from here";
Text* finalText = NULL;
finalText = new Text(22, 0, 400, false, newText, 0.0f, 0.0f, 1024.0f, 200.0f);
scene.AddText(finalText);

Any help would be good, i'm totally at a loss :(

This is my entire main.cpp, minus all the irrelevant crap.

// Trim fat from windows
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include "directXManager.h"
#include "Timer.h"
#include "Renderer.h"
#include "Camera.h"
#include "Text.h"
#include <time.h>

// Message Pump prototype
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

void setupWindow(WNDCLASS &wc, HINSTANCE hinstance, HWND &wnd);

void function(D3DXVECTOR3* vector[3], Renderer &scene);

// Program entry point
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
// Timer functionality
Timer timer;
timer.Init();

/* initialize random seed: */
srand ( time(NULL) );


// Step One:    Register a window type
WNDCLASS wc;    

// Step Two: Create a window of that type.
HWND wnd = NULL;

setupWindow(wc, hinstance, wnd);


// Initialise Direct3D
if (!DirectXManager::Instance().InitDirect3D(wnd, WINDOW_WIDTH, WINDOW_HEIGHT, true)) { return 0; }

// Make a local copy of our IDirect3DDevice
IDirect3DDevice9* device = NULL;
device = DirectXManager::Instance().GetDevice();

// Start Timer
timer.Reset();
float timeCurrent = timer.GetTime();
float timePrevious = timer.GetTime();
float deltaTime = 0.0f;

// create camera
Camera camera;

// create renderer
Renderer scene;

if (device) { } // end if()


// Step Four: Create a message pump.
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
while(msg.message != WM_QUIT)
{
    // Handle time for current frame
    timeCurrent = timer.GetTime();
    deltaTime = timeCurrent - timePrevious;

    // Process all windows messages, any messages that are 
    // currently available will be processed now.
    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } // end while()

    if (msg.message != WM_QUIT)
    {
        // create vectors
        D3DXVECTOR3* vector[3];
        vector[0] = new D3DXVECTOR3(-3.57f, 6.43f, 8.30f);
        vector[1] = new D3DXVECTOR3(5.67f, 3.23f, -8.72f);
        vector[2] = new D3DXVECTOR3(0.0f, 0.0f, 0.0f);

        function(vector, scene);

        // render scene
        scene.Render(deltaTime, DirectXManager::Instance().GetDevice(), camera);

    } // end if()

    // Update time values
    timePrevious = timeCurrent;
} // end while()

// Cleanup
DirectXManager::Instance().Release();

return 0;
} // end WinMain


// Message Pump body
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
  {
  case WM_DESTROY:
{
  DirectXManager::Instance().Release();
  PostQuitMessage(0);
  break;
}

  // Pressing of escape key - quit
  case WM_KEYDOWN:
    {
      switch (wParam)
      {
    case VK_ESCAPE: PostQuitMessage(0); DirectXManager::Instance().Release();      break;
  }

  break;
}
  default:
    break;
  }

  return DefWindowProc(hwnd, msg, wParam, lParam);
}


// this will setup all the values for the DX window
void setupWindow(WNDCLASS &wc, HINSTANCE hinstance, HWND &wnd)
{
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = NULL;
wc.hIcon = LoadIcon(hinstance, "ApplicationIcon");
wc.hInstance = hinstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "TuteWindow";
wc.lpszMenuName = "";
wc.style = CS_CLASSDC;


if (RegisterClass(&wc))
{
    // Step Two: Create a window of that type
    wnd = CreateWindow("TuteWindow", WINDOW_TITLE, WS_SYSMENU, SCREEN_WIDTH / 2 - (WINDOW_WIDTH / 2), SCREEN_HEIGHT / 2 - (WINDOW_HEIGHT / 2), WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hinstance, 0);
} else {
    //return 0;
} // end if()

// Step Three: Show the window.
if (wnd)
{
    UpdateWindow(wnd);
    ShowWindow(wnd, SW_SHOW);
} // end if()
} // end setupWindow()



void function(D3DXVECTOR3* vector[3], Renderer &scene) {

char vectorText[80];
sprintf(vectorText, "vector%i = [%f, %f, %f]", 1, vector[0]->x, vector[0]->y, vector[0]->z);

char* newText =  vectorText;
Text* finalText = NULL;
finalText = new Text(22, 0, 400, false, newText, 0.0f, 0.0f, 1024.0f, 200.0f);
scene.AddText(finalText);

} // end function
+1  A: 

Can you check if the sprintf works correctly before you call the new Text()

I reckon that you may be blowing the stack. The stack blowout may not be due to the allocation, rather with what happens to the buffer user.

You may have to consider what happens to the buffer you send to Text().

then rinse and repeat.

Preet Sangha
80 bytes don't blow the stack.. and if they do you get a segmentation fault.
ypnos
char *vectorText = "This prints garbage";Works, but not with sprintf :(
Dr Kheese
What about my second question?
Preet Sangha
This is the constructor for the Text class. Text(int height, int width, int weight, bool italic, const char* text, float left, float top, float right, float bottom); This all ends up getting passed into D3DXCreateFont(device, height, width, weight, 1, italic, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Verdana", I don't know if any of this helps :(
Dr Kheese
thank you. what are the constraints on the buffer passed in. Have you checked that the buffer is ok before you call new Text() using the sprintf
Preet Sangha
+6  A: 

Problem is that your char[] lies on the stack and probably directx accesses it after you left the function and it became invalid.

In your latter case, char* newText = "Text will work from here", the array is a constant that is stored in program memory in the heap.

ypnos