An answer to this question can be found here: stackoverflow.com
I'm trying to learn how to do some basic work in OpenGL 2.0 and I'm having difficulties getting any vertex data to show up on the screen. Right now I'm at a loss for where my problem is. I've gone through a number of examples and nothing obvious stands out for me as wrong in my code, but I'm sure I'm missing something simple. I'll try to be short with my code.
Thank you.
bool GameCore::Start(int iCmdShow)
{
const LPCWSTR appname = TEXT("Maze Game");
// Create the Window and kill the program if this fails.
if(!wm->Create(appname))
{
return FALSE;
}
// Initialize OpenGL
wm->InitGraphics();
cam = wm->cam;
Vector3 *v = new Vector3(0.0f,0.0f,0.0f);
wm->testSprite = new Sprite(v);
// Start the update loop.
_beginthread(&GameCore::Execute, 0, this);
// Blocking function to run the application.
wm->RunWindow(iCmdShow);
return true;
}
// Initialize OpenGL graphics
void OpenGLWM::InitGraphics()
{
hDC = GetDC(hWnd);
SetupPixelFormat();
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
glClearColor(1, 0, 0, 0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
GLenum err = glewInit();
if (GLEW_OK != err)
{
// Add error handling.
}
cam = new Camera(0, 0, -10);
program = new ShaderProgram();
program->Initialize();
}
// Set up pixel format for graphics initialization
void OpenGLWM::SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;
ppfd = &pfd;
ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_COLORINDEX;
ppfd->cColorBits = 16;
ppfd->cDepthBits = 16;
ppfd->cAccumBits = 0;
ppfd->cStencilBits = 0;
pixelformat = ChoosePixelFormat(hDC, ppfd);
SetPixelFormat(hDC, pixelformat, ppfd);
}
// Camera Constructor
Camera::Camera(double dX, double dY, double dZ)
{
Vector3 V(dX, dY, dZ);
Vector3 R(0,0,0);
Initialization(V, R);
}
bool ShaderProgram::Initialize()
{
GLint giLinked;
GLbyte vShaderStr[] =
"#version 110 \n"
"attribute vec3 in_Position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(in_Position, 1.0);\n"
"}\n";
GLbyte pShaderStr[] =
"#version 110 \n"
"precision mediump float;\n"
"void main()\n"
"{\n"
"gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
"}\n";
// Load the shaders
vertexShader.LoadShader((const char *)&vShaderStr, GL_VERTEX_SHADER);
pixelShader.LoadShader((const char *)&pShaderStr, GL_FRAGMENT_SHADER);
guiProgram = glCreateProgram();
if(guiProgram == 0)
{
return false;
}
// Add the shaders to the program
glAttachShader(guiProgram, vertexShader.guiShader);
glAttachShader(guiProgram, pixelShader.guiShader);
// Bind the position coordinates
glBindAttribLocation(guiProgram, 0, "in_Position");
// Link the program
glLinkProgram(guiProgram);
int iError = glGetError();
// Get the link status
glGetProgramiv(guiProgram, GL_LINK_STATUS, &giLinked);
if(giLinked == 0)
{
// Add error handling.
return false;
}
return true;
}
GLuint BaseShader::LoadShader(const char *cShaderSrc, GLenum type)
{
GLint guiCompiled;
// Creates an empty shader object.
guiShader = glCreateShader(type);
if(guiShader == 0)
{
return 0;
}
// Load the shader.
glShaderSource(guiShader, 1, &cShaderSrc, NULL);
// Compile the shader
glCompileShader(guiShader);
// Check the compile status
glGetShaderiv(guiShader, GL_COMPILE_STATUS, &guiCompiled);
if(guiCompiled == 0)
{
// TODO: ADD ERROR LOGGING
GLint infoLen = 0;
glGetShaderiv(guiShader, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char *)malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(guiShader, infoLen, NULL, infoLog);
free(infoLog);
}
return 0;
}
return guiShader;
}
// Sprite inherits from Render Object
Sprite::Sprite(Vector3 *_vPosition)
{
// Initialize the position.
vPosition = _vPosition;
// Create verticies
vertexStruct * v = new vertexStruct[4];
v[0].SetPosition(-2, 2, -40);
v[0].SetColor(128, 128, 128, 255);
v[1].SetPosition(2, 2, -40);
v[1].SetColor(128, 128, 128, 255);
v[2].SetPosition(2, -2, -40);
v[2].SetColor(128, 128, 128, 255);
v[3].SetPosition(-2, -2, -40);
v[3].SetColor(128, 128, 128, 255);
// Create the indicies.
GLubyte * i = new GLubyte[6];
i[0] = 0;
i[1] = 1;
i[2] = 2;
i[3] = 0;
i[4] = 2;
i[5] = 3;
Initialize(v, 4, i, 6);
}
void RenderObject::Initialize(vertexStruct *_vertices, unsigned int _uiNumVertices, GLubyte *_indices, unsigned int _uiNumIndicies)
{
vertices = _vertices;
indices = _indices;
uiNumVertices = _uiNumVertices;
uiNumIndices = _uiNumIndicies;
CreateBufferObjects();
}
void RenderObject::CreateBufferObjects()
{
// Get an id for the Vector3 buffer.
glGenBuffers((GLsizei)1, &uiVertexBuffer);
// Bind the buffer so we can "upload" the data.
glBindBuffer(GL_ARRAY_BUFFER, uiVertexBuffer);
// Upload the data to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexStruct) * uiNumVertices, vertices, GL_STATIC_DRAW);
// Get an id for the indice buffer.
glGenBuffers(1, &uiIndiceBuffer);
// Bind the indice buffer so we can "upload" the data.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uiIndiceBuffer);
// Upload the data to OpenGL.
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * uiNumIndices, indices, GL_STATIC_DRAW);
}
bool WindowManager::RunWindow(int iCmdShow)
{
// Display the window
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
// Event loop
while (1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (!GetMessage(&msg, NULL, 0, 0))
{
return TRUE;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// It would be better if this was its own thread.
if(!DoWork())
{
return false;
}
}
return true;
}
// "Draw" function.
bool OpenGLWM::DoWork()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program->guiProgram);
testSprite->Draw();
// Show the new scene
SwapBuffers(hDC);
return true;
}
void RenderObject::Draw()
{
// Bind the vertex buffer.
glBindBuffer(GL_ARRAY_BUFFER, uiVertexBuffer);
// Set where the vertex data is.
glVertexAttribPointer(VertexEnum::Data, 3, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), 0);
glEnableVertexAttribArray(0);//VertexEnum::Data);
// Load the colors.
glVertexAttribPointer(VertexEnum::Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 12, (void*)offsetof(vertexStruct, color));
glEnableVertexAttribArray(1);//VertexEnum::Color);
// Bind the indice buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uiIndiceBuffer);
glDrawElements(GL_TRIANGLE_STRIP, uiNumIndices, GL_UNSIGNED_BYTE, 0);
}
Update:
Here is the glViewPort code:
void OpenGLWM::ResizeGraphics()
{
// Get new window size
RECT rect;
int width;
int height;
GLfloat aspect;
GetClientRect(hWnd, &rect);
width = rect.right;
height = rect.bottom;
aspect = (GLfloat)width / height;
// Adjust graphics to window size
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, aspect, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
// Call the base function
WindowManager::ResizeGraphics();
}
