[Very noobish] Cube not render

Started by
8 comments, last by cifa 11 years ago

Hi there, first I want to point out that I'm a huge begginer in OpenGL actually I've started today, but I've done a bit in WebGL.
Trying to port, from WebGL a simple program that show a cube and this is the result:

(I know that it may seem a strange way to do this, but I need a port that have to look like my WebGL sample)


// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <iostream>


// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <GL/glfw.h>

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace glm;

#include <common/shader.hpp>

int viewportWidth=1024;
int viewporthHeight=768;


int initWindow(char * nome);
void drawScene();
void initBuffers();
void cleanBuffers();
void initShaders();
void mvMatrixPush();
void mvMatrixPop();
void printMat(glm::mat4  mat);
void setMatrixUniform();

struct programField {
	GLint vertexPositionAttribute;
	GLint vertexColorAttribute;
	GLint pMatrixUniform;
	GLint mvMatrixUniform;
	
};

struct bufferField{
	int itemSize;
	int numItems;
};

struct programField program;

GLuint programID;
GLuint VertexArrayID;
GLuint vertexbuffer;

int main( void )
{
	initWindow("Prova");
	initShaders();
	initBuffers();
	do{	
		drawScene();
	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
		   glfwGetWindowParam( GLFW_OPENED ) );
	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	return 0;
}

void initShaders(){
	programID = LoadShaders( "vs.vertexshader", "fs.fragmentshader" );
	glUseProgram(programID);	
	program.vertexPositionAttribute=glGetAttribLocation(programID, "aVertexPosition");
	glEnableVertexAttribArray(program.vertexPositionAttribute);
	program.vertexColorAttribute=glGetAttribLocation(programID, "aVertexColor");
	glEnableVertexAttribArray(program.vertexColorAttribute);
	program.pMatrixUniform=glGetUniformLocation(programID, "uPMatrix");
	program.mvMatrixUniform=glGetUniformLocation(programID, "uMVMatrix");
}

glm::mat4 mvMatrix = glm::mat4(1.0);
glm::mat4 pMatrix = glm::mat4(1.0);
std::stack<glm::mat4> mvMatrixStack;      

void mvMatrixPush(){
	glm::mat4 copy = glm::mat4(1.0);
	copy = mvMatrix;
	mvMatrixStack.push(copy);
}

void mvMatrixPop(){
	if(mvMatrixStack.size()==0){
		printf("Invalid pop");
		return;
	}
	mvMatrix=mvMatrixStack.top();
	mvMatrixStack.pop();
}

void setMatrixUniform(){
	glUniformMatrix4fv(program.pMatrixUniform, 1, GL_FALSE, &pMatrix[0][0]);
	glUniformMatrix4fv(program.mvMatrixUniform, 1, GL_FALSE, &mvMatrix[0][0]);
}

float degToRad(int degrees){
	return degrees*3.14f/180;
}


GLuint vertexPositionBuffer;
struct bufferField vertexPositionField;
GLuint vertexColorBuffer;
struct bufferField vertexColorField;
GLuint vertexIndexBuffer;
struct bufferField vertexIndicesField;

void initBuffers(){

	glGenBuffers(1, &vertexPositionBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer);

	static const GLfloat vertices[] = { 
//Faccia frontale
	-1.0f,-1.0f,1.0f,
	1.0f,-1.0f,1.0f,
	1.0f,1.0f,1.0f,
	-1.0f,1.0f,1.0f,

	//Faccia retro
	-1.0f,-1.0f,-1.0f,
	-1.0f,1.0f,-1.0f,
	1.0f,1.0f,-1.0f,
	1.0f,-1.0f,-1.0f,

	//Faccia in cima
	-1.0f,1.0f,-1.0f,
	-1.0f,1.0f,1.0f,
	1.0f,2.0f,1.0f,
	1.0f,1.0f,-1.0f,

	//Faccia sotto
    -1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    1.0f, -1.0f,  1.0f,
    -1.0f, -1.0f,  1.0f,

    //Faccia destra
    1.0f, -1.0f, -1.0f,
    1.0f,  1.0f, -1.0f,
    1.0f,  1.0f,  1.0f,
    1.0f, -1.0f,  1.0f,

    //Faccia sinistra
	-1.0f, -1.0f, -1.0f,
    -1.0f, -1.0f,  1.0f,
    -1.0f,  1.0f,  1.0f,
    -1.0f,  1.0f, -1.0f

	};


	
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
	vertexPositionField.itemSize=3;
	vertexPositionField.numItems=24;

	
	glGenBuffers(1, &vertexColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);

	static const GLfloat colors[]={
	
	//Faccia frontale
	1.0f,0.0f,0.0f,1.0f,
	1.0f,0.0f,0.0f,1.0f,
	1.0f,0.0f,0.0f,1.0f,
	1.0f,0.0f,0.0f,1.0f,

	//Retro
	0.0f,1.0f,0.0f,1.0f,
	0.0f,1.0f,0.0f,1.0f,
	0.0f,1.0f,0.0f,1.0f,
	0.0f,1.0f,0.0f,1.0f,

	//In cima
	0.0f,0.0f,1.0f,1.0f,
	0.0f,0.0f,1.0f,1.0f,
	0.0f,0.0f,1.0f,1.0f,
	0.0f,0.0f,1.0f,1.0f,

	//Faccia sotto
	1.0f,1.0f,0.0f,1.0f,
	1.0f,1.0f,0.0f,1.0f,
	1.0f,1.0f,0.0f,1.0f,
	1.0f,1.0f,0.0f,1.0f,

	//Faccia destra
	0.0f,1.0f,1.0f,1.0f,
	0.0f,1.0f,1.0f,1.0f,
	0.0f,1.0f,1.0f,1.0f,
	0.0f,1.0f,1.0f,1.0f,

	//Faccio sinistra
	1.0f,0.0f,1.0f,1.0f,
	1.0f,0.0f,1.0f,1.0f,
	1.0f,0.0f,1.0f,1.0f,
	1.0f,0.0f,1.0f,1.0f
	};

	glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
	vertexColorField.itemSize=4;
	vertexColorField.numItems=24;

	glGenBuffers(1, &vertexIndexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);

	static const GLint indices[]={
	0,1,2,	0,2,3,
	4,5,6,	4,6,7,
	8,9,10,	8,10,11,
	12,13,14,	12,14,15,
	16,17,18,	16,18,19,
	20,21,22,	20,22,23
	};

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	vertexIndicesField.itemSize=1;
	vertexIndicesField.numItems=36;
}



void drawScene(){

		// Clear the screen
		glClear( GL_COLOR_BUFFER_BIT);
		pMatrix=glm::perspective(45.0f, float(viewportWidth/viewporthHeight), 0.1f, 100.0f);

		mvMatrix = glm::mat4(1.0);
		mvMatrix=glm::translate(mvMatrix, glm::vec3(-1.5f,0.0f,-8.0f));

		mvMatrixPush();

		glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer);
		glVertexAttribPointer(
			program.vertexPositionAttribute,                 
			vertexPositionField.itemSize,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		
		glBindBuffer(GL_ARRAY_BUFFER, vertexColorBuffer);
		glVertexAttribPointer(
			program.vertexColorAttribute,                 
			vertexColorField.itemSize,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);


		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
		setMatrixUniform();
		glDrawElements(GL_TRIANGLES,vertexIndicesField.numItems, GL_UNSIGNED_SHORT, 0);


		// Swap buffers
		glfwSwapBuffers();

}

int initWindow(char * nome){
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		return -1;
	}

	glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);
	glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
	glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
	glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// Open a window and create its OpenGL context
	if( !glfwOpenWindow( viewportWidth, viewporthHeight, 0,0,0,0, 32,0, GLFW_WINDOW ) )
	{
		fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
		glfwTerminate();
		return -1;
	}

	glfwSetWindowTitle(nome );

	// Ensure we can capture the escape key being pressed below
	glfwEnable( GLFW_STICKY_KEYS );

	// Dark blue background
	glClearColor(0.9f, 0.9f, 0.9f, 0.0f);

	glEnable(GL_DEPTH_TEST);

		// Initialize GLEW
	glewExperimental = true; // Needed for core profile
	if (glewInit() != GLEW_OK) {
		fprintf(stderr, "Failed to initialize GLEW\n");
		return -1;
	}

	return 0;
}

With shaders that are:


#version 330 core
	attribute vec3 aVertexPosition;
	attribute vec4 aVertexColor;

	uniform mat4 uMVMatrix;
	uniform mat4 uPMatrix;

	varying vec4 vColor;

	void main(void){
		gl_Position=uPMatrix*uMVMatrix*vec4(aVertexPosition, 1.0);
		vColor=aVertexColor;

	}


#version 330 core

	precision mediump float;

	varying vec4 vColor;

	void main(void){
		gl_FragColor=vColor;
	}

(Sorry for the indenting, bad copy-paste)


It compiles, but no cube is showed,it is surely a banal issue but I don't know how to find it out.

Sorry for the probably stupid question and if my English is bad smile.png

Thanks a lot!

Advertisement

That's a lot of code to read through. You should probably try to start with just a camera and a basic shape (without any shaders or buffers or whatever) and expand from there step by step. Running such complex code as yours usually never works at the first time.

That's a lot of code to read through. You should probably try to start with just a camera and a basic shape (without any shaders or buffers or whatever) and expand from there step by step. Running such complex code as yours usually never works at the first time.

Thanks for the reply first of all.

Secondly, I've ""learned"" the basic GL concept with WebGL, what I need (for many reason that are boring to explain) is a 1:1 port of my WebGL code to OpenGL.

Oh and that code on WebGL (with a basic port to javascript) works pretty well

You've enabled depth testing but you appear to only be clearing the colour buffer and not the depth buffer. It's possible that your first frame is rendering successfully but then each successive frame is failing because the depth test is failing.

One thing I noticed is that you're defining the indices as int, but you're using them as unsigned short.


static const GLint indices[] = { ... };
glDrawElements(GL_TRIANGLES,vertexIndicesField.numItems, GL_UNSIGNED_SHORT, 0); 

I would probably use GLuint indices[] and GL_UNSIGNED_INT for glDrawElements.

Derp

Thank you all for the replies

You've enabled depth testing but you appear to only be clearing the colour buffer and not the depth buffer. It's possible that your first frame is rendering successfully but then each successive frame is failing because the depth test is failing.

Uh I copy-pasted the wrong version I guess, because I clear it on my source. Probably it was a desperate test.

Even with clearing GL:DEPTH_BUFFER_BIT nothing changes.

One thing I noticed is that you're defining the indices as int, but you're using them as unsigned short.


static const GLint indices[] = { ... };
glDrawElements(GL_TRIANGLES,vertexIndicesField.numItems, GL_UNSIGNED_SHORT, 0); 

I would probably use GLuint indices[] and GL_UNSIGNED_INT for glDrawElements.

Thanks I didn't see it, but even with that fix it still doesn't work.

It doesn't work also with drawArrays.

You don't seem to call mvMatrixPop, but it doesn't probably matter that much though. Also, I'm not sure if GLSL 3.3 core likes keywords "attribute" and "varying" because those are deprecated, use "in" and "out" instead. You should also use glGetProgram and glGetProgramInfoLog for grabbing some information about the shader program.

You could also try running the application in gDebugger, it's an awesome program for debugging OpenGL applications.

Derp

You don't seem to call mvMatrixPop, but it doesn't probably matter that much though. Also, I'm not sure if GLSL 3.3 core likes keywords "attribute" and "varying" because those are deprecated, use "in" and "out" instead. You should also use glGetProgram and glGetProgramInfoLog for grabbing some information about the shader program.

You could also try running the application in gDebugger, it's an awesome program for debugging OpenGL applications.

Thanks! No I used mvMatrixPop in a more complex example, that after those problem I've shrinked to this one.

glGetProgramInfoLog is called inside


LoadShaders( "vs.vertexshader", "fs.fragmentshader" );

that I haven't post it here because found on online tutorial. And everything (compiling and linking) it's fine with shaders

I also used gDebugger but I haven't found out the problem :(

Gah, I'm not so familiar with these core profiles and stuff, but I think I found your problem: http://www.gamedev.net/topic/609951-glvertexattribpointer-giving-gl-invalid-operation/
As V-Man says there, "If you are using core profile on GL 3.2, then you must use VAO when you call glBindBuffer and glVertexAttribPointer."
I found my way to that thread by starting up gDebugger and turned on breakpoints on errors, then noticed an invalid operation on glVertexAttribPointer, and googled for "glVertexAttribPointer invalid operation"
Maybe try with these hints and you should at least see something:

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 0);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

And btw, in c++, int/int = int, so your aspect ratio is wrong, float(viewportWidth)/viewporthHeight would work better.

Derp

Gah, I'm not so familiar with these core profiles and stuff, but I think I found your problem: http://www.gamedev.net/topic/609951-glvertexattribpointer-giving-gl-invalid-operation/
As V-Man says there, "If you are using core profile on GL 3.2, then you must use VAO when you call glBindBuffer and glVertexAttribPointer."
I found my way to that thread by starting up gDebugger and turned on breakpoints on errors, then noticed an invalid operation on glVertexAttribPointer, and googled for "glVertexAttribPointer invalid operation"
Maybe try with these hints and you should at least see something:

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 0);
//glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

And btw, in c++, int/int = int, so your aspect ratio is wrong, float(viewportWidth)/viewporthHeight would work better.

Oh! With those hints it works fine, I'm going to study those core profile-stuff biggrin.png

Thank you so much!

This topic is closed to new replies.

Advertisement