Jump to content
  • Advertisement
Sign in to follow this  
Labrasones

OpenGL (Help)My matrices give me a blank screen!

This topic is 2361 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?
.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Is there a difference between
gl_Position = ProjMat*ModelViewMat*in_Position;
gl_Position = (ProjMat*ModelViewMat)*in_Position;
gl_Position = ProjMat*(ModelViewMat*in_Position);


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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].


Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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. Edited by Labrasones

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!