(Help)My matrices give me a blank screen!

Started by
8 comments, last by Labrasones 11 years, 10 months ago
I'm very new to C++ and OpenGL, and I've manage to cobble together a working bit of code from what I've learned from a bunch of OpenGL tutorials. And it works! Until I try and use any matrices to render in 3D. I don't think I'm doing anything wrong, and I'm pretty sure the matrices aren't filled with 0's. But I've hit a dead end and I don't know where to go, or what might be the problem. If you could help me I'd be very grateful. If you need some of the code I haven't posted, let me know.
(I'm using the GLM library for all the matrix stuff)

opengl_4.cpp

#include "opengl_4.h"
/-snipped-/ Creating of rendering context and whatnot

void OpenGLContext::setupScene(void) {
glClearColor(0.3f,0.3f,0.3f,0.0f); //set the clear color to a dark grey
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
shader = new Shader("basic.vert","basic.frag");
item = new Object();
item->makeDefaultObject();
}

void OpenGLContext::reshapeWindow(int w, int h) {
windowWidth = w; //Set the window width
windowHeight = h; //Set thewindow height
glViewport(0,0, windowWidth, windowHeight); //Set the viewport size to fill the window
ProjectionMatrix = glm::perspective(
45.0f,
(float)windowWidth / windowHeight,
0.1f,
500.0f
);
}

void OpenGLContext::renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //Clear required buffers
ModelViewMatrix = glm::mat4(1.0f);//glm::translate(glm::mat4(1.0f), glm::vec3(0.0f,0.0f, -5.0f));
shader->bind();
item->bind();
glUniformMatrix4fv(shader->locations[0], 1, GL_FALSE, &ProjectionMatrix[0][0]);
glUniformMatrix4fv(shader->locations[1], 1, GL_FALSE, &ModelViewMatrix[0][0]);
glDrawElements(GL_TRIANGLES, item->polyCount*3, GL_UNSIGNED_INT, (GLvoid*)0);
shader->unbind();
item->unbind();
SwapBuffers(hdc); //swap buffers so we can see our rendering
}


object.cpp

//Object file
#include "object.h"

Object::Object()
{
makeDefaultObject();
}
Object::~Object()
{
}
void Object::makeDefaultObject()
{
vert Vertices[4] =
{
{{ 0.0f, 0.5f, 0.0f, 1.0f},{0.0f,0.0f,1.0f,1.0f}},
{{ 0.0f,-0.5f,-0.5f, 1.0f},{0.0f,1.0f,0.0f,1.0f}},
{{ 0.5f,-0.5f, 0.5f, 1.0f},{1.0f,0.0f,0.0f,1.0f}},
{{-0.5f,-0.5f, 0.5f, 1.0f},{1.0f,0.0f,0.0f,1.0f}}
};
vertCount = 4;

poly Polys[4] =
{
{0,1,2},
{2,0,3},
{3,1,0},
{1,3,2}
};
polyCount = 4;

glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Polys), Polys, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);

glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertices[0]), 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertices[0]), (void*)sizeof(Vertices[0].position));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);

glBindVertexArray(0);

}

void Object::bind()
{
glBindVertexArray(_vao);
}
void Object::unbind()
{
glBindVertexArray(0);
}


shader.cpp

#include "shader.h"
#include <string.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

static char* textFileRead(const char *fileName) {
char* text = "NULL";

if (fileName != NULL) {
FILE *file = fopen(fileName, "rt");

if (file != NULL) {
fseek(file, 0, SEEK_END);
int count = ftell(file);
rewind(file);

if (count > 0) {
text = (char*)malloc(sizeof(char) * (count + 1));
count = fread(text, sizeof(char), count, file);
text[count] = '\0';
}
fclose(file);
}
}
return text;
}

Shader::Shader() {

}

Shader::Shader(const char *vsFile, const char *fsFile) {
init(vsFile, fsFile);
}

void Shader::init(const char *vsFile, const char *fsFile) {
shader_vp = glCreateShader(GL_VERTEX_SHADER);
shader_fp = glCreateShader(GL_FRAGMENT_SHADER);

const char* vsText = textFileRead(vsFile);
const char* fsText = textFileRead(fsFile);

if (vsText == NULL || fsText == NULL) {
cerr << "Either vertex shader or fragment shader file not found." << endl;
return;
}

glShaderSource(shader_vp, 1, &vsText, 0);
glShaderSource(shader_fp, 1, &fsText, 0);

glCompileShader(shader_vp);
glCompileShader(shader_fp);

shader_id = glCreateProgram();
glAttachShader(shader_id, shader_fp);
glAttachShader(shader_id, shader_vp);
glLinkProgram(shader_id);

locations[0] = glGetUniformLocation(shader_id, "ProjMat");
locations[1] = glGetUniformLocation(shader_id, "ModelViewMat");
glBindAttribLocation(shader_id, 0, "in_Position"); //Bind a constant attribute location for positions of vertices
glBindAttribLocation(shader_id, 1, "in_Color"); //Bind another constant attribute location, this time for color
}

Shader::~Shader() {
glDetachShader(shader_id, shader_fp);
glDetachShader(shader_id, shader_vp);

glDeleteShader(shader_fp);
glDeleteShader(shader_vp);
glDeleteProgram(shader_id);
}

unsigned int Shader::id() {
return shader_id;
}

void Shader::bind() {
glUseProgram(shader_id);
}

void Shader::unbind() {
glUseProgram(0);
}


Vertex shader

#version 330

layout(location = 0) in vec4 in_Position;
layout(location = 1) in vec4 in_Colour;
out vec4 mid_Colour;

uniform in mat4 ProjMat;
uniform in mat4 ModelViewMat;

void main(void)
{
gl_Position = ProjMat*ModelViewMat*in_Position;
mid_Colour = in_Colour;
}

Fragment shader

#version 330

in vec4 mid_Colour;

out vec4 out_Color;


void main(void)
{
out_Color = mid_Colour;
}


sorry about the huge page, I can't figure out how to shrink the code boxes.
Advertisement
I'm not sure if the "in" qualifier can be used with "uniform". The GLSL specification says "linkage into a shader from a previous stage, variable is copied in".

I didn't see any error checking code in your program, you should do some error checking in the initialization stage to ensure your shader is working for you.

Your matrices is not 0s in your C++ code, but it may be zero in the shader.
You should not be able to use the in qualifier on a uniform. The in qualifier is only for attributes (in vec4 in_Position) and varyings (in vec4 mid_Colour) so it is possible that the driver is shitty. is it AMD or nVidia?
.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Its nVidia number 285.62. The gpu is the 460M (laptop). And your right excali, I haven't got any error checking going on :S. I just sort of assumed the shader was working because the object got colour, which is probably bad. I'll definitely implement error checking. However, I tried removing the "in"s already, and it didn't make any difference. And I'm pretty sure that the matrices aren't 0 in the shader because when I use each row as the colour vector, it does have colours. Again, I'm new, so I don't know if that means anything. Another thing I tried was multiplying the matrices on the cpu, then transferring the combined matrix to the shader, and that worked. Which is great, but I wish I knew why it doesn't work on the shader.
Is there a difference between
gl_Position = ProjMat*ModelViewMat*in_Position;
gl_Position = (ProjMat*ModelViewMat)*in_Position;
gl_Position = ProjMat*(ModelViewMat*in_Position);


Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
I was starting to wonder if I had the matrix multiplication out of order, but I'm not sure which order is correct. Although, when I tried using the same order of multiplication as on the cpu side, it still didn't work. (I multiplied like so (Projection*Model*View)*in_position [I also split the modelview to try and simplify a bit] This order worked when multiplied on cpu, but not when it is in the shader)

My biggest source of confusion on the matter right now is why does it work if I multiply the matrices on the cpu, and then transfer them to the shader, then multiply the position with the combined matrix. However, this same set of steps, when done entirely on the shader, gives me a blank screen.

Is there a difference between
gl_Position = ProjMat*ModelViewMat*in_Position;
gl_Position = (ProjMat*ModelViewMat)*in_Position;
gl_Position = ProjMat*(ModelViewMat*in_Position);


There shouldn't be any difference in the result, but the computation cost is different.



My biggest source of confusion on the matter right now is why does it work if I multiply the matrices on the cpu, and then transfer them to the shader, then multiply the position with the combined matrix. However, this same set of steps, when done entirely on the shader, gives me a blank screen.


Try to use trivial transformations and see if it works, i.e. using identity matrices as your transformation matrices and draw something in [-1,1] x [-1,1] x [-1,-1].


It did work fine with identity matrices. There was no change between no matrices and trivial matrices.
So I figured out the problem! I was using the wrong versions. I had openGL 3.2 for the context, and shader version 330. I'm not sure whether one is ahead of the other, but as soon as I changed them to 4.0 and 400, it worked fine.
I'm sure if I had proper error checking I would have been warned of it :S Definitely something for the next version!
Happy New Year everyone! May the new year bring you all success in your projects!
So, I recently lost all my data (long story, due to user error :| ) And I've hit exactly the same problem again. Except this time it doesn't even work if I multiply the shaders on the CPU. I'm basing it off of a tutorial I found here -> http://openglbook.co...hird-dimension/
I've converted it to use GLM Math instead of the math functions included in the tutorial. That's the only change though. If there is a specific bit of the code you would like to see, let me know and I'll post it.

Solutions I've tried so far:
-Transposing the matrices before transferring them to shader.
- Using identity matrices, doesn't give the blank screen.
- Made sure version numbers are the same
- Used same matrix multiplication order as last time.

None of these have made any difference. The only thing I've managed to do is fill the entire screen with 2 triangles when I disable the OpenGL culling operations. This problem seems to be kicking my ass over and over again and I wish I knew why I can't get it to work. Any suggestions would be very useful.

This topic is closed to new replies.

Advertisement