This is exercises for my course in computer graphics, but I'm not asking for solutions, just for a way to be able to actually work on the exercises since right now I can't because all the output is producing is black window - I know what it's supposed to produce since I worked on it on school computers and am trying to work on it from home now.
The code works fine on school computers, and I've asked the TAs for help, but they've been unsuccesful so far in locating my problem.
The school computers run on VS 2010 windows 7, while I only have VS 2013 windows 8.1 available. When I opened the project the first time it asked me to convert it to VS2013 etc. and I did so.
I am able to run some other exercises just fine, but I have a problem with all exercises above 2.1.
The code below is from exercise 2.2
// 02561-02-02
#include <iostream>
#include <string>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "Angel.h"
using namespace std;
using namespace Angel;
int WINDOW_WIDTH = 500;
int WINDOW_HEIGHT = 500;
GLuint shaderProgram;
GLuint projectionUniform,
modelViewUniform,
colorUniform;
GLuint positionAttribute;
GLuint unitCubeVertexArrayObject,
axisVertexArrayObject,
vertexBuffer;
const int axisSize = 6;
struct Vertex {
vec4 position;
};
void loadShader();
void display();
GLuint loadBufferData(Vertex* vertices, int vertexCount);
void buildUnitCube() {
const int cubeSize = 8;
Vertex cubeData[cubeSize] = {
{ vec4( 1.0, 1.0, 1.0, 1.0 ) },
{ vec4( 1.0, 0.0, 1.0, 1.0 ) },
{ vec4( 1.0, 1.0, 0.0, 1.0 ) },
{ vec4( 1.0, 0.0, 0.0, 1.0 ) },
{ vec4(-0.0, 1.0, 0.0, 1.0 ) },
{ vec4(-0.0, 0.0, 0.0, 1.0 ) },
{ vec4(-0.0, 1.0, 1.0, 1.0 ) },
{ vec4(-0.0, 0.0, 1.0, 1.0 ) }
};
unitCubeVertexArrayObject = loadBufferData(cubeData, cubeSize);
}
void buildAxis() {
Vertex axisData[axisSize] = {
{vec4(0., 0., 0., 1.0)}, // v0
{vec4(4., 0., 0., 1.0)}, // vx
{vec4(0., 4., 0., 1.0)}, // vy
{vec4(0., 0., 4., 1.0)}, // vz
{vec4(1., 0., 0., 1.0)}, // v0x1
{vec4(1., 3., 0., 1.0)} // vyx1
};
axisVertexArrayObject = loadBufferData(axisData, axisSize);
}
GLuint loadBufferData(Vertex* vertices, int vertexCount) {
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(positionAttribute);
glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);
return vertexArrayObject;
}
void loadShader(){
shaderProgram = InitShader("const-shader.vert", "const-shader.frag", "fragColor");
projectionUniform = glGetUniformLocation(shaderProgram, "projection");
if (projectionUniform == GL_INVALID_INDEX) {
cerr << "Shader did not contain the 'projection' uniform."<<endl;
}
modelViewUniform = glGetUniformLocation(shaderProgram, "modelView");
if (modelViewUniform == GL_INVALID_INDEX) {
cerr << "Shader did not contain the 'modelView' uniform."<<endl;
}
colorUniform = glGetUniformLocation(shaderProgram, "color");
if (colorUniform == GL_INVALID_INDEX) {
cerr << "Shader did not contain the 'color' uniform."<<endl;
}
positionAttribute = glGetAttribLocation(shaderProgram, "position");
if (positionAttribute == GL_INVALID_INDEX) {
cerr << "Shader did not contain the 'position' attribute." << endl;
}
}
void drawWireUnitCube() {
GLuint indices[24] = {
0,1,
1,3,
3,2,
2,0,
4,5,
5,7,
7,6,
6,4,
7,1,
6,0,
4,2,
5,3
};
glBindVertexArray(unitCubeVertexArrayObject);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, indices);
}
void drawAxis() {
GLuint indices[8] = {
0,1,
0,2,
0,3,
4,5
};
glBindVertexArray(axisVertexArrayObject);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, indices);
}
void display() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
mat4 projection = Ortho(-6., 6., -6., 6., -6., 10.);
glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, projection);
mat4 modelView(1.0f);
vec4 red(1.0, 0.0, 0.0, 1.0);
glUniform4fv(colorUniform, 1, red);
glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
drawAxis();
// todo multiply model transformations
vec4 white(1.0, 1.0, 1.0, 1.0);
glUniform4fv(colorUniform, 1, white);
glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
drawWireUnitCube();
glutSwapBuffers();
Angel::CheckError();
}
void reshape(int W, int H) {
WINDOW_WIDTH = W;
WINDOW_HEIGHT = H;
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitContextVersion(3, 2);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_3_2_CORE_PROFILE);
glutCreateWindow("02561-02-02");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);
Angel::InitOpenGL();
loadShader();
buildUnitCube();
buildAxis();
Angel::CheckError();
glutMainLoop();
}
Your code requests a Core Profile context:
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
but it's not completely compatible with the Core Profile. In the Core Profile, all vertex data needs to be sourced from buffers. Passing client side arrays for vertex data is not supported anymore. This includes index data. So the following is not allowed:
GLuint indices[8] = {
0,1,
0,2,
0,3,
4,5
};
glBindVertexArray(axisVertexArrayObject);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, indices);
You need to store the indices in a GL_ELEMENT_ARRAY_BUFFER. Extend the signature of loadBufferData() function to also take index data, and add code to also create an index buffer:
GLuint loadBufferData(Vertex* vertices, int vertexCount
GLuint* indices, int indexCount) {
...
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLuint), indices, GL_STATIC_DRAW);
return vertexArrayObject;
}
Then the draw functions look like this:
glBindVertexArray(axisVertexArrayObject);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, 0);
Related
I'm new to OpenGl and I was working on texturing. I want to draw one image on three sides and another image on other three sides of cube. I'm unable to do it. I want to know at what point in my code is cube being drawn on window?
This is my code:
#include "06_texturing.hpp"
#include "texture.hpp"
GLuint shaderProgram;
GLuint vbo[2], vao[2];
GLuint tex;
glm::mat4 rotation_matrix;
glm::mat4 projection_matrix;
glm::mat4 c_rotation_matrix;
glm::mat4 lookat_matrix;
glm::mat4 model_matrix;
glm::mat4 view_matrix;
glm::mat4 modelview_matrix;
glm::mat3 normal_matrix;
GLuint uModelViewMatrix;
GLuint viewMatrix;
GLuint normalMatrix;
//-----------------------------------------------------------------
//6 faces, 2 triangles/face, 3 vertices/triangle
const int num_vertices = 36;
glm::vec4 texCoordinates[8];
//Eight vertices in homogenous coordinates
glm::vec4 positions[8] = {
glm::vec4(-0.5, -0.5, 0.5, 1.0),
glm::vec4(-0.5, 0.5, 0.5, 1.0),
glm::vec4(0.5, 0.5, 0.5, 1.0),
glm::vec4(0.5, -0.5, 0.5, 1.0),
glm::vec4(-0.5, -0.5, -0.5, 1.0),
glm::vec4(-0.5, 0.5, -0.5, 1.0),
glm::vec4(0.5, 0.5, -0.5, 1.0),
glm::vec4(0.5, -0.5, -0.5, 1.0)
};
glm::vec4 normals[8] = {
glm::vec4(-0.5, -0.5, 0.5, 1.0),
glm::vec4(-0.5, 0.5, 0.5, 1.0),
glm::vec4(0.5, 0.5, 0.5, 1.0),
glm::vec4(0.5, -0.5, 0.5, 1.0),
glm::vec4(-0.5, -0.5, -0.5, 1.0),
glm::vec4(-0.5, 0.5, -0.5, 1.0),
glm::vec4(0.5, 0.5, -0.5, 1.0),
glm::vec4(0.5, -0.5, -0.5, 1.0)
};
//RGBA colors
glm::vec4 colors[8] = {
glm::vec4(0.0, 0.0, 0.0, 1.0),
glm::vec4(1.0, 0.0, 0.0, 1.0),
glm::vec4(1.0, 1.0, 0.0, 1.0),
glm::vec4(0.0, 1.0, 0.0, 1.0),
glm::vec4(0.0, 0.0, 1.0, 1.0),
glm::vec4(1.0, 0.0, 1.0, 1.0),
glm::vec4(1.0, 1.0, 1.0, 1.0),
glm::vec4(0.0, 1.0, 1.0, 1.0)
};
glm::vec2 t_coords[4] = {
glm::vec2( 0.0, 0.0),
glm::vec2( 0.0, 1.0),
glm::vec2( 1.0, 0.0),
glm::vec2( 1.0, 1.0)
};
glm::vec4 color(0.6, 0.6, 0.6, 1.0);
glm::vec4 black(0.1, 0.1, 0.1, 1.0);
glm::vec4 white(0.2, 0.7, 0.7, 1.0);
glm::vec4 red(1.0, 0.2, 0.2, 1.0);
glm::vec4 yellow(0.8, 0.8, 0.0, 1.0);
glm::vec4 green(0.2, 0.7, 0.2, 1.0);
glm::vec4 blue(0.2, 0.2, 0.7, 1.0);
int tri_idx=0;
glm::vec4 v_positions[num_vertices];
glm::vec4 v_colors[num_vertices];
glm::vec4 v_normals[num_vertices];
glm::vec2 tex_coords[num_vertices];
// quad generates two triangles for each face and assigns colors to the vertices
void quad(int a, int b, int c, int d, glm::vec4 color)
{
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[a];
v_normals[tri_idx] = normals[a];
tex_coords[tri_idx] = t_coords[1];
tri_idx++;
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[b];
v_normals[tri_idx] = normals[b];
tex_coords[tri_idx] = t_coords[0];
tri_idx++;
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[c];
v_normals[tri_idx] = normals[c];
tex_coords[tri_idx] = t_coords[2];
tri_idx++;
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[a];
v_normals[tri_idx] = normals[a];
tex_coords[tri_idx] = t_coords[1];
tri_idx++;
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[c];
v_normals[tri_idx] = normals[c];
tex_coords[tri_idx] = t_coords[2];
tri_idx++;
v_colors[tri_idx] = color; v_positions[tri_idx] = positions[d];
v_normals[tri_idx] = normals[d];
tex_coords[tri_idx] = t_coords[3];
tri_idx++;
}
// generate 12 triangles: 36 vertices and 36 colors
void colorcube(void)
{
quad( 1, 0, 3, 2, red);
quad( 2, 3, 7, 6, green);
quad( 3, 0, 4, 7, white);
quad( 6, 5, 1, 2, yellow);
quad( 4, 5, 6, 7, black);
quad( 5, 4, 0, 1, blue);
}
//-----------------------------------------------------------------
void initBuffersGL(void)
{
// Load shaders and use the resulting shader program
std::string vertex_shader_file("06_vshader.glsl");
std::string fragment_shader_file("06_fshader.glsl");
std::vector<GLuint> shaderList;
shaderList.push_back(csX75::LoadShaderGL(GL_VERTEX_SHADER, vertex_shader_file));
shaderList.push_back(csX75::LoadShaderGL(GL_FRAGMENT_SHADER, fragment_shader_file));
shaderProgram = csX75::CreateProgramGL(shaderList);
glUseProgram( shaderProgram );
// getting the attributes from the shader program
GLuint vPosition = glGetAttribLocation( shaderProgram, "vPosition" );
GLuint vColor = glGetAttribLocation( shaderProgram, "vColor" );
GLuint vNormal = glGetAttribLocation( shaderProgram, "vNormal" );
GLuint texCoord = glGetAttribLocation( shaderProgram, "texCoord" );
uModelViewMatrix = glGetUniformLocation( shaderProgram, "uModelViewMatrix");
normalMatrix = glGetUniformLocation( shaderProgram, "normalMatrix");
viewMatrix = glGetUniformLocation( shaderProgram, "viewMatrix");
// Load Textures
GLuint tex=LoadTexture("images/all1.bmp",256,256);
GLuint tex2=LoadTexture("images/another.bmp",256,256);
glBindTexture(GL_TEXTURE_2D, tex);
//Ask GL for two Vertex Attribute Objects (vao) , one for the sphere and one for the wireframe
glGenVertexArrays (2, vao);
//Ask GL for two Vertex Buffer Object (vbo)
glGenBuffers (2, vbo);
//Set 0 as the current array to be used by binding it
glBindVertexArray (vao[0]);
//Set 0 as the current buffer to be used by binding it
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
colorcube();
//Copy the points into the current buffer
glBufferData (GL_ARRAY_BUFFER, sizeof (v_positions) + sizeof(tex_coords) + sizeof(v_normals), NULL, GL_STATIC_DRAW);
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(v_positions), v_positions );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(v_positions), sizeof(tex_coords), tex_coords);
glBufferSubData( GL_ARRAY_BUFFER, sizeof(tex_coords)+sizeof(v_positions), sizeof(v_normals), v_normals );
// set up vertex array
//Position
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
//Textures
glEnableVertexAttribArray( texCoord );
glVertexAttribPointer( texCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions)) );
//Normal
glEnableVertexAttribArray( vNormal );
glVertexAttribPointer( vNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions)+sizeof(tex_coords)) );
}
void renderGL(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
rotation_matrix = glm::rotate(glm::mat4(1.0f), glm::radians(xrot), glm::vec3(1.0f,0.0f,0.0f));
rotation_matrix = glm::rotate(rotation_matrix, glm::radians(yrot), glm::vec3(0.0f,1.0f,0.0f));
rotation_matrix = glm::rotate(rotation_matrix, glm::radians(zrot), glm::vec3(0.0f,0.0f,1.0f));
model_matrix = rotation_matrix;
//Creating the lookat and the up vectors for the camera
c_rotation_matrix = glm::rotate(glm::mat4(1.0f), glm::radians(c_xrot), glm::vec3(1.0f,0.0f,0.0f));
c_rotation_matrix = glm::rotate(c_rotation_matrix, glm::radians(c_yrot), glm::vec3(0.0f,1.0f,0.0f));
c_rotation_matrix = glm::rotate(c_rotation_matrix, glm::radians(c_zrot), glm::vec3(0.0f,0.0f,1.0f));
glm::vec4 c_pos = glm::vec4(c_xpos,c_ypos,c_zpos, 1.0)*c_rotation_matrix;
glm::vec4 c_up = glm::vec4(c_up_x,c_up_y,c_up_z, 1.0)*c_rotation_matrix;
//Creating the lookat matrix
lookat_matrix = glm::lookAt(glm::vec3(c_pos),glm::vec3(0.0),glm::vec3(c_up));
//creating the projection matrix
projection_matrix = glm::frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 5.0);
view_matrix = projection_matrix*lookat_matrix;
glUniformMatrix4fv(viewMatrix, 1, GL_FALSE, glm::value_ptr(view_matrix));
// Draw the sphere
modelview_matrix = view_matrix*model_matrix;
glUniformMatrix4fv(uModelViewMatrix, 1, GL_FALSE, glm::value_ptr(modelview_matrix));
normal_matrix = glm::transpose (glm::inverse(glm::mat3(modelview_matrix)));
glUniformMatrix3fv(normalMatrix, 1, GL_FALSE, glm::value_ptr(normal_matrix));
// glBindTexture(GL_TEXTURE_2D, tex);
glBindVertexArray (vao[0]);
glDrawArrays(GL_TRIANGLES, 0, num_vertices);
}
int main(int argc, char** argv)
{
//! The pointer to the GLFW window
GLFWwindow* window;
//! Setting up the GLFW Error callback
glfwSetErrorCallback(csX75::error_callback);
//! Initialize GLFW
if (!glfwInit())
return -1;
//We want OpenGL 4.0
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//This is for MacOSX - can be omitted otherwise
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//We don't want the old OpenGL
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//! Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(512, 512, "CS475/CS675 Tutorial 6: Texturing a cube", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
//! Make the window's context current
glfwMakeContextCurrent(window);
//Initialize GLEW
//Turn this on to get Shader based OpenGL
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
{
//Problem: glewInit failed, something is seriously wrong.
std::cerr<<"GLEW Init Failed : %s"<<std::endl;
}
//Keyboard Callback
glfwSetKeyCallback(window, csX75::key_callback);
//Framebuffer resize callback
glfwSetFramebufferSizeCallback(window, csX75::framebuffer_size_callback);
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
//Initialize GL state
csX75::initGL();
initBuffersGL();
// Loop until the user closes the window
while (glfwWindowShouldClose(window) == 0)
{
// Render here
renderGL();
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
I want to change in it to render different images on different sides.
If you want to use 2 completely different textures, in the fragment shader, then you have to bind the textures to 2 different texture units. The texture unit can be set by glActiveTexture:
GLuint tex=LoadTexture("images/all1.bmp",256,256);
GLuint tex2=LoadTexture("images/another.bmp",256,256);
int unit_tex0 = 0; // texture unit 0 and binding point 0
int unit_tex1 = 1; // texture unit 1 and binding point 1
glActiveTexture( GL_TEXTURE0 + unit_tex0 );
glBindTexture(GL_TEXTURE_2D, tex);
glActiveTexture( GL_TEXTURE0 + unit_tex1 );
glBindTexture(GL_TEXTURE_2D, tex2);
Further you have to declare 2 texture samplers in the fragment shader. The texture samplers have to be associated to the texture units. Since GLSL version 4.2 this can be done in the fragment shader by specifying binding points:
#version 420
layout (binding = 0) uniform sampler2D u_texture0;
layout (binding = 1) uniform sampler2D u_texture1;
Alternatively you can assign the texture unit index, to the texture sampler uniform by glUniform1i:
uniform sampler2D u_texture0;
uniform sampler2D u_texture1;
GLuint location_tex0 = glGetUniformLocation( shaderProgram, "u_texture0" );
GLuint location_tex1 = glGetUniformLocation( shaderProgram, "u_texture1" );
glUniform1i( location_tex0, unit_tex0 );
glUniform1i( location_tex1, unit_tex1 );
To distinguish between the sides of the cubes, you can use the built in vertex shader variable gl_VertexID.
Create a flat out variable of type int in the vertex shader and pass the vertex id to the fragment shader:
flat out int vertex_id;
void main()
{
.....
vertex_id = gl_VertexID;
.....
}
In the fragment shader yo can decide which texture you want to use by the id corresponding to the vertex coordinate. Note, you have 36 coordinates, the first 3 sides have the ids form 0 to 17 and the other the ids form 18 to 35:
flat in int vertex_id;
void main()
{
.....
if ( vertex_id < 18 )
fragColor = texture(u_texture0, vertUV);
else
fragColor = texture(u_texture1, vertUV);
.....
}
I'm trying to make a program with OpenGL that creates two rectangles, but my problem is that when I create my two model_views, the first one gets overwritten by the second one so only one rectangle is displaying and I'm not sure how to display both. I posted the entire code. How do I get both triangles to render?
using namespace std;
#include "vgl.h"
#include "LoadShaders.h"
#include "glm\glm.hpp"
#include "glm\gtc\matrix_transform.hpp"
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
GLuint location;
const GLuint NumVertices = 4;
//---------------------------------------------------------------------
// Setting up our pipeline and preparing to draw
void init(void)
{
//Defining the name of our shader files
ShaderInfo shaders[] = {
{ GL_VERTEX_SHADER, "triangles.vert" },
{ GL_FRAGMENT_SHADER, "triangles.frag" },
{ GL_NONE, NULL }
};
//Loading and attaching shaders to our pipeline
GLuint program = LoadShaders(shaders);
glUseProgram(program); //My Pipeline is set up
// Coordinates of vertices (Square)
GLfloat vertices[NumVertices][2] = {
{ -0.3, -0.45 },
{ 0.3, -0.45 },
{ 0.3, 0.45 },
{ -0.3, 0.45 }
};
// Colors for vertices in {R, G, B} mode
GLfloat colorData[NumVertices][3] = {
{ 1,0,0 }, //Red
{ 0,1,0 }, //Green
{ 0,0,1 }, //Blue
{ 1,1,1 } //White
};
glGenBuffers(2, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindAttribLocation(program, 0, "vPosition");
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW);
glBindAttribLocation(program, 1, "vertexColor");
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
location = glGetUniformLocation(program, "model_matrix");
}
//---------------------------------------------------------------------
//This is done by using glutDisplayFunc function. Look at the main method
void drawScene(void)
{
//Clear the screen and preparing to draw
glClear(GL_COLOR_BUFFER_BIT);
/////////THIS IS WERE I CREATE RECTANGLES
//Sun
glm::mat4 model_view = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, 0.0));
model_view = glm::scale(model_view, glm::vec3(0.5, 0.5, 0)); //shrink it
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]);
glm::mat4 model_view2 = glm::translate(glm::mat4(1.0), glm::vec3(0.5, 0.0, 0.0));
model_view2 = glm::scale(model_view2, glm::vec3(0.5, 0.5, 0)); //shrink it
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view2[0][0]);
//The following function passes the generated rotation function into the vertex-shader
//Starting the pipeline
glDrawArrays(GL_QUADS, 0, NumVertices);
glDrawArrays(GL_QUADS, 0, NumVertices);
//Flush the image onto the window (screen)
glFlush();
}
//The registration happens in the main() function using
glutIdleFunc(runEveryFrame) function.
void runEveryFrame()
{
//Increasing our rotation angle
rotate_value += 0.001;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
//Initializing to draw
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(512, 512);
glutCreateWindow("Hello World");
glewInit();
//init function is defined above
init();
//Registering the display function
glutDisplayFunc(drawScene);
//Registering the idle function
glutIdleFunc(runEveryFrame);
//glutMainLoop enters the event processing loop
glutMainLoop();
}
You call glDrawArrays with the same arguments, without changing any uniform between the two calls. My bet would that the two shapes are drawed, one over the other.
You'd have to call glUniformXXX before each glDrawArrays calls, if the uniform data (the model/view matrices) have changed :
void drawScene(void) {
glClear(GL_COLOR_BUFFER_BIT);
//first draw call with model/view transformation 1
glm::mat4 model_view = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, 0.0));
model_view = glm::scale(model_view, glm::vec3(0.5, 0.5, 0)); //shrink it
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]);
glDrawArrays(GL_QUADS, 0, NumVertices);
//second draw call with model/view transformation 2
glm::mat4 model_view2 = glm::translate(glm::mat4(1.0), glm::vec3(0.5, 0.0, 0.0));
model_view2 = glm::scale(model_view2, glm::vec3(0.5, 0.5, 0));
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view2[0][0]);
glDrawArrays(GL_QUADS, 0, NumVertices);
//Flush the image onto the window (screen)
glFlush();
}
I am using Xcode to write openGL. What I am doing is to draw a circle, a triangle, and a square.
However, I found that my circle only can display on
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
the triangle and square can only display on glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA | GLUT_SINGLE);
How can i make them display together?
Here is part of my entire code:
#include "Angel.h" //includes gl.h, glut.h and other stuff...
void m_glewInitAndVersion(void); //pre-implementation declaration (could do in header file)
void close(void);
//Mesh 0
GLuint buffer[3];
GLuint VAO[3];
GLuint color_loc;
GLuint program;
const int NumVertices = 4;
// Vertices of a unit cube centered at origin, sides aligned with axes
vec2 points[4] = {
vec2( 0.25, 0.25),
vec2( 0.75, 0.25),
vec2( 0.75, 0.75),
vec2( 0.25, 0.75)
};
vec2 points2[3]={
vec2(-1,-1),
vec2(0,-1),
vec2(0,-0.7)};
// RGBA colors
vec4 blue_opaque = vec4( 0.0, 0.0, 1.0, 1.0 );
vec4 red_opaque = vec4(1.0, 0.0, 0.0, 1.0);
//----------------------------------------------------------------------------
// OpenGL initialization
void
init()
{
glClearColor( 1.0, 1.0, 1.0, 1.0 );
// glColor3f(1.0, 0.0, 0.0);
// glMatrixMode(GL_PROJECTION);
// glLoadIdentity();
// gluOrtho2D(-3.5, 3.5, -3.5, 3.5);
// Create and initialize a buffer object
glGenBuffers( 2, buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer[0] );
glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );
// Load shaders and use the resulting shader program
program = InitShader( "vshader00_v150.glsl", "fshader00_v150.glsl" );
glUseProgram( program );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
//Set up VAO
glGenVertexArrays(2,VAO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER,buffer[0]);
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
color_loc = glGetUniformLocation(program, "color");
//triangle
// glBindVertexArray(VAO[1]);
// glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
// glBufferData(GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
// glUseProgram(program);
// glEnableVertexAttribArray(vPosition);
// glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
}
//----------------------------------------------------------------------------
void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
// const float PI=3.14159;
// glBegin(GL_TRIANGLE_FAN);
// All triangles fan out starting with this point
// glVertex2f (0.0,0.0);
// for (int i = 0; i <=361; i++)
// {
// glColor3f(float(rand())/float(RAND_MAX),
// float(rand())/float(RAND_MAX),
// float(rand())/float(RAND_MAX));
// glVertex2f(2.0*cos(i*PI/180), 2.0*sin(i*PI/180));
// }
// glEnd();
glBindVertexArray(VAO[0]);
glDrawArrays( GL_TRIANGLE_FAN, 0, NumVertices );
glUseProgram(program);
glUniform4fv(color_loc, 1, blue_opaque);
// glBindVertexArray(VAO[1]);
// glDrawArrays( GL_TRIANGLE_FAN, 0, 3);
// glUseProgram(program);
// glUniform4fv(color_loc, 1, red_opaque);
glFlush();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
#ifdef __APPLE__
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA | GLUT_SINGLE);
#else
glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE);
#endif
glutInitWindowSize( 500, 500 );
glutCreateWindow( "CS 432 Hello World" );
m_glewInitAndVersion();
init();
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutWMCloseFunc(close);
glutMainLoop();
return 0;
}
Your circle code doesn't work with GLUT_3_2_CORE_PROFILE because glBegin, glColor3f, glVertex2f and glEnd were removed in OpenGL 3, so OpenGL 3.2 (or later) doesn't have them.
I'm not sure exactly why your triangle and square code doesn't work without GLUT_3_2_CORE_PROFILE, but consider that VAOs were added in OpenGL 3, and when you don't specify GLUT_3_2_CORE_PROFILE, you get a version before 3.
Pick a version and stick with it.
I'm working with old opengl 3.0, I have verified my system runs above 3.0, and for some reason i'm getting an error whenever I use any of these functions/terms:
glBindVertexArrays,
glGenBuffers,
GL_ARRAY_BUFFER,
glBindBuffers,
GL_STATIC_DRAW
Why is this happening?!?!
I am compiling in C and C++ in a .cpp file
I can give you guys the entire project if you like it's just a demo for VAOs... but I thought that this might be a common problem that people experience...
OpenGL has been very taxing on me, it seems it has LOTS of linker errors and problems that I've just never had with anything else.
If I can't fix this i'm going to have to move my project to a higher opengl version and forget supporting legacy systems.
EDIT: Here is the code
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// EXTRAS
#include <GL/gl.h> // Default OpenGL library
#include <GL/glu.h> // Utils
#include <stdlib.h>
#include <stdio.h>
#include "glext.h"
// EOF EXTRAS
#include <iostream>
#include <stdlib.h>
#define ARRAY_SIZE( array ) sizeof( array ) / sizeof( array[0] )
#define BUFFER_OFFSET(offset) ((GLvoid*) NULL + offset)
#define NumberOf(array) (sizeof(array)/sizeof(array[0]))
typedef struct {
GLfloat x, y, z;
} vec3;
typedef struct {
vec3 xlate;
GLfloat angle;
vec3 axis;
} XForm;
enum { Cube, Cone, NumVAOs };
GLuint VAO[NumVAOs];
GLenum PrimType[NumVAOs];
GLsizei NumElements[NumVAOs];
XForm Xform[NumVAOs] = {
{{ -2.0, 0.0, 0.0 }, 0.0, { 0.0, 1.0, 0.0 }},
{{ 0.0, 0.0, 2.0 }, 0.0, { 1.0, 0.0, 0.0 }}
};
GLfloat Angle = 0.0;
void init()
{
glEnableClientState(GL_NORMAL_ARRAY);
enum { Vertices, Colors, Elements, NumVBOs };
GLuint buffers[NumVBOs];
glGenVertexArrays(NumVAOs, VAO);
{
GLfloat cubeVerts[][3] = {
{ -1.0, -1.0, -1.0 },
{ -1.0, -1.0, 1.0 },
{ -1.0, 1.0, -1.0 },
{ -1.0, 1.0, 1.0 },
{ 1.0, -1.0, -1.0 },
{ 1.0, -1.0, 1.0 },
{ 1.0, 1.0, -1.0 },
{ 1.0, 1.0, 1.0 }
};
GLfloat cubeColors[][3] = {
{ 0.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 1.0, 1.0 },
{ 1.0, 0.0, 0.0 },
{ 1.0, 0.0, 1.0 },
{ 1.0, 1.0, 0.0 },
{ 1.0, 1.0, 1.0 }
};
GLubyte cubeIndices[] = {
0, 1, 3, 2,
4, 6, 7, 5,
2, 3, 7, 6,
0, 4, 5, 1,
0, 2, 6, 4,
1, 5, 7, 3
};
glBindVertexArray(VAO[Cube]);
glGenBuffers(NumVBOs, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVerts),
cubeVerts, GL_STATIC_DRAW);
glVertexpointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors),
cubeColors, GL_STATIC_DRAW);
glVertexpointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);
PrimType[Cube] = GL_QUADS;
NumElements[Cube] = NumberOf(cubeIndices);
}
{
int i, idx;
float dTheta;
#define NumConePoints 36
//Add one for cone
GLfloat coneVerts[NumConePoints+1][3] = {
{0.0, 0.0, 1.0}
};
GLfloat coneColors[NumConePoints+1][3] = {
{1.0,1.0,1.0}
};
GLubyte coneIndices[NumConePoints+1];
dTheta = 2*M_PI / (NumConePoints - 1);
idx = 1;
for (i = 0; i < NumConePoints; ++i, ++idx){
float theta = i*dTheta;
coneVerts[idx][0] = cos(theta);
coneVerts[idx][1] = sin(theta);
coneVerts[idx][2] = 0.0;
coneColors[idx][0] = cos(theta);
coneColors[idx][1] = sin(theta);
coneColors[idx][2] = 0.0;
coneIndices[idx] = idx;
}
glBindVertexArray(VAO[Cone]);
glGenBuffers(NumVBOs, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices]);
glBufferData(GL_ARRAY_BUFFER, sizeof(coneVerts), coneVerts, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors]);
glBufferData(GL_ARRAY_BUFFER, sizeof(coneColors), coneColors, GL_STATIC_DRAW);
glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(coneIndices), coneIndices, GL_STATIC_DRAW);
PrimType[Cone] = GL_TRIANGLE_FAN;
NumElements[Cone] = NumberOf(coneIndices);
}
glEnable(GL_DEPTH_TEST);
}
void display()
{
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(Angle, 0.0, 1.0, 0.0);
for (i = 0; i < NumVAOs; ++i)
{
glPushMatrix();
glTranslatef(Xform[i].xlate.x, Xform[i].xlate.y, Xform[i].xlate.z);
glBindVertexArray(VAO[i]);
glDrawElements(PrimType[i], NumElements[i],
GL_UNSIGNED_BYTE, BUFFER_OFFSET(0))
glPopMatrix();
}
glPopMatrix();
glutSwapBuffers();
}
I'am trying to draw a icosahedron using OpenGL 3.3+ so i may subdivided later on to make it a sphere, but I keep getting this error in VS2010 Express:
Stack around the variable '_vertices' was corrupted
Here is the code:
#include "Angel.h"
int CurrentWidth = 800,
CurrentHeight = 600,
WindowHandle = 0;
unsigned FrameCount = 0;
/*Default values used to draw the object*/
float X = 0.525731112119133606f;
float Z = 0.850650808352039932f;
GLuint
VertexShaderId,
FragmentShaderId,
ProgramId,
VaoId,
VboId,
ColorBufferId,
IndexBufferId;
const GLchar* VertexShader =
{
"#version 400\n"\
"layout(location=0) in vec4 in_Position;\n"\
"layout(location=1) in vec4 in_Color;\n"\
"out vec4 ex_Color;\n"\
"void main(void)\n"\
"{\n"\
" gl_Position = in_Position;\n"\
" ex_Color = in_Color;\n"\
"}\n"
};
const GLchar* FragmentShader =
{
"#version 400\n"\
"in vec4 ex_Color;\n"\
"out vec4 out_Color;\n"\
"void main(void)\n"\
"{\n"\
" out_Color = vec4( 0.0, 0.0, 1.0, 1.0 );\n"\
"}\n"
};
void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitWindowSize(CurrentWidth, CurrentHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
if(WindowHandle < 1) {
exit(EXIT_FAILURE);
}
glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction);
glutIdleFunc(IdleFunction);
glutTimerFunc(0, TimerFunction, 0);
glutCloseFunc(Cleanup);
}
void RenderFunction(void)
{
++FrameCount;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 60, GL_UNSIGNED_BYTE, (GLvoid*)0);
glutSwapBuffers();
glutPostRedisplay();
}
void CreateVBO(void)
{
/*Starting points*/
GLfloat Vertices[][4] =
{{-X,0.0f,Z, 1.0}, {X,0.0f,Z, 1.0}, {-X,0.0f,-Z, 1.0}, {X,0.0f,-Z, 1.0},
{0.0f,Z,X, 1.0}, {0.0f,Z,-X, 1.0}, {0.0f,-Z,X, 1.0}, {0.0f,-Z,-X, 1.0},
{Z,X,0.0f, 1.0}, {-Z,X,0.0f, 1.0}, {Z,-X,0.0f, 1.0}, {-Z,-X,0.0f, 1.0}};
/*Incdices on how to draw the object using triangles*/
GLubyte Indices[] =
{1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4,
1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2,
3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0,
10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7};
/*Filling up the points which i need to draw from the start*/
GLfloat _vertices[60];
for (int i = 0; i < 60; ++i) {
_vertices[(3*i)+0] = Vertices[Indices[i]][0];
_vertices[(3*i)+1] = Vertices[Indices[i]][1];
_vertices[(3*i)+2] = Vertices[Indices[i]][2];
}
/*End of nodes generation*/
GLenum ErrorCheckValue = glGetError();<br/>
glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);<br/>
glGenBuffers(1, &VboId);
glBindBuffer(GL_ARRAY_BUFFER, VboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &IndexBufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
ErrorCheckValue = glGetError();
if(ErrorCheckValue != GL_NO_ERROR)
{
exit(-1);
}
}
Note: I only put the function of drawing and not everything,and that without using the Indices array it would draw some weird stuff. Thanks
for (int i = 0; i < 60; ++i) {
should be
for (int i = 0; i < 20; ++i) {
Otherwise, you're going out of bounds and modifying memory outside of the array, hence, the stack around the array is being corrupted.
You're writing out of array bounds. _vertices is an array of 60 GLfloats, but you're accessing it in the range 0 .. 3*59 + 2.