Reputation: 1364
By taking away the ComputePositonOffsets() and AdjustVertexData() methods, I can display a single triangle, but I added some button functionality to spin it to see if there was more anywhere else in the screen, and I can't figure out why it generates a black screen.
#include <algorithm>
#include <string>
#include <vector>
#include <stdio.h>
#include <glload/gl_3_2_comp.h>
#include <GL/freeglut.h>
#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
double rotate_y = 0;
double rotate_x = 0;
GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile) {
GLuint shader = glCreateShader(eShaderType);
const char *strFileData = strShaderFile.c_str();
glShaderSource(shader, 1, &strFileData, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
const char *strShaderType = NULL;
switch (eShaderType) {
case GL_VERTEX_SHADER:
strShaderType = "vertex";
break;
case GL_GEOMETRY_SHADER:
strShaderType = "geometry";
break;
case GL_FRAGMENT_SHADER:
strShaderType = "fragment";
break;
}
fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType,strInfoLog);
delete[] strInfoLog;
}
return shader;
}
GLuint CreateProgram(const std::vector<GLuint> &shaderList) {
GLuint program = glCreateProgram();
for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
glAttachShader(program, shaderList[iLoop]);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
fprintf(stderr, "Linker failure: %s\n", strInfoLog);
delete[] strInfoLog;
}
for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
glDetachShader(program, shaderList[iLoop]);
return program;
}
GLuint theProgram;
const std::string strVertexShader("#version 330\n"
"layout(location = 0) in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\n");
const std::string strFragmentShader("#version 330\n"
"out vec4 outputColor;\n"
"void main()\n"
"{\n"
" outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
"}\n");
void InitializeProgram() {
std::vector<GLuint> shaderList;
shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
theProgram = CreateProgram(shaderList);
std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader);
}
const float vertexPositions2[] = { 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5,
-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5,
-0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5 };
GLuint positionBufferObject;
GLuint vao;
void InitializeVertexBuffer() {
glGenBuffers(1, &positionBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions2), vertexPositions2,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void init() {
InitializeProgram();
InitializeVertexBuffer();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
void ComputePositionOffsets(float &fXOffset, float &fYOffset) {
const float fLoopDuration = 5.0f;
const float fScale = 3.14159f * 2.0f / fLoopDuration;
float fElapsedTime = glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
float fCurrTimeThroughLoop = fmodf(fElapsedTime, fLoopDuration);
fXOffset = cosf(fCurrTimeThroughLoop * fScale) * 0.5f;
fYOffset = sinf(fCurrTimeThroughLoop * fScale) * 0.5f;
}
void AdjustVertexData(float fXOffset, float fYOffset) {
std::vector<float> fNewData(ARRAY_COUNT(vertexPositions2));
memcpy(&fNewData[0], vertexPositions2, sizeof(vertexPositions2));
for (int iVertex = 0; iVertex < ARRAY_COUNT(vertexPositions2); iVertex +=
4) {
fNewData[iVertex] += fXOffset;
fNewData[iVertex + 1] += fYOffset;
}
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertexPositions2), &fNewData[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//Called to update the display.
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
void display() {
glUseProgram(theProgram);
float fXOffset = 0.0f, fYOffset = 0.0f;
ComputePositionOffsets(fXOffset, fYOffset);
AdjustVertexData(fXOffset, fYOffset);
//glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
GLubyte indices[] = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11,
8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22,
23, 20 }; // back
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glFlush();
glUseProgram(0);
glutSwapBuffers();
}
//Called whenever the window is resized. The new window size is given, in pixels.
//This is an opportunity to call glViewport or glScissor to keep up with the change in size.
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
}
//Called whenever a key on the keyboard was pressed.
//The key is given by the ''key'' parameter, which is in ASCII.
//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to
//exit the program.
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 27:
glutLeaveMainLoop();
return;
}
// Right arrow - increase rotation by 5 degree
if (key == GLUT_KEY_RIGHT) rotate_y += 5;
// Left arrow - decrease rotation by 5 degree
else if (key == GLUT_KEY_LEFT) rotate_y -= 5;
else if (key == GLUT_KEY_UP) rotate_x += 5;
else if (key == GLUT_KEY_DOWN) rotate_x -= 5;
// Request display update
glutPostRedisplay();
}
unsigned int defaults(unsigned int displayMode, int &width, int &height) {
return displayMode;
}
Upvotes: 1
Views: 630
Reputation: 839
const float vertexPositions2[] = {0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5};
I'm guessing that is a list of 3D vectors making up a cube, seeing as there are 24 (6 faces * 4 corners) indices used lower down in your code and all the values are either 0.5 or -0.5. However, you tell OpenGL that this is a list of vectors with 4 componenents, rather than 3:
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
It's quite unusual to set that second parameter to 4. If you set it to 3, OpenGL will fill in the w
component to 1 for you. Try that. I think you will see a square if you do that.
On top of this, I don't see a perspective projection matrix anywhere. If you don't have one, you will get a 2D projection instead of a 3D one. Things won't appear the way you want them to. You'll want to get that in before you implement rotation and moving around.
These lines below will have no effect on your program, and they do not belong in a modern graphics program. They change the matrices in the fixed-function matrix stack, which you don't (and I think can't, since you're using GLSL 330) use in your shader. You have to define the matrices as uniform variables yourself.
glLoadIdentity();
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
Upvotes: 2