I tried rendering a cube using OpenGL, in Windows. But the display window is black. I enabled the Z-Buffer, I clear the depth bit in the glClear function, etc. But no luck. And the problem is that every example or documentation I follow, is incomplete, or omit some information, and I'm very, very confused right now. I don't know what am I doing right and what am I doing wrong.
All I want is to display a cube, to know that the renderer is ready for 3D graphics (I can display 2D graphics with no problems). Nothing else.
This is the code of my main program:
#include "demo.h"
#include "renderfunc.c"
HDC hDC;
HGLRC hRC;
void enableGL(HWND hWnd)
{
hDC = GetDC(hWnd);
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0 };
if(!hDC)
{
MessageBox(hWnd,L"Can't Create A GL Device Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if(!nPixelFormat)
{
MessageBox(hWnd,L"Can't find a proper Pixel Format.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
SetPixelFormat(hDC, nPixelFormat, &pfd);
/* Those lines has to be here*/
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* UNCOMMENT THIS SECTION FOR 3D */
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL); //In some examples this is GL_LESS
glDepthMask(GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Accurate perspective calculations
return;
}
GLvoid ChangeSize(GLsizei width, GLsizei height)
{
if(height==0)
height=1;
glViewport(0,0,width,height);
//glLoadIdentity();
/* THIS SECTION IS FOR 3D GRAPHICS */
/* Comment glLoadIdentity above, and uncomment this section */
/* If you enable Z-buffer */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
enableGL(hWnd);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
ReleaseDC(hWnd,hDC);
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
case WM_PAINT:
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* GL ANIMATION GOES HERE */
//Change this for whatever you want to render
renderCubeTest();
/* -------------------- */
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
return 0;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
return 0;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
//String with the name of the class of our window
LPCTSTR classname = L"OpenGL";
//String with the title of our window
LPCTSTR windowtitle = L"Cubes Demo By Ninjihaku Software";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
wc.hIcon = NULL;
wc.hCursor = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(RegisterClass(&wc) == 0)
return false;
//hWnd = CreateWindow(classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 640, 480, NULL, NULL, hInstance, NULL);
hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 640, 480, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
return FALSE;
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
return (int) msg.wParam;
}
Then the renderCubeTest() function included in renderfunc.c:
void renderCubeTest()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glFlush();
glPopMatrix();
return;
}
I hope someone can help me and tell me what's wrong with this.
glDepthFunc(GL_EQUAL);
I suspect this is the problem - what it basically does is tell OpenGL that pixels should only be rendered to the screen if the new pixel's depth value is equal to the current pixel's depth value. This is most certainly not what you want.
Instead, you should use either GL_LEQUAL (note the "L" before "EQUAL") or GL_LESS, as these are the normal comparison functions.
Related
I used matrices from cglm to modify the camera and what I should've seen on the screen is a small square, but nothing shows up. I have this code:
#define GLEW_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include<stdio.h>
#include<stdlib.h>
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<stdbool.h>
#include<string.h>
#include<stb/stb_image.h>
#include<cglm/cglm.h>
const unsigned int width = 1054;
const unsigned int height = 1057;
GLint uniColor;
GLint xploc;
GLint yploc;
void key_callback();
int main(){
if(!glfwInit()){
printf("Failed to initialize glfw!\n");
return 1;
}else{
printf("Successfully initialized glfw!\n");
}
//Set up GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(width, height, "Title", NULL, NULL);
glfwSetKeyCallback(window, key_callback);
if(!window){
printf("Window creation failed!\n");
return 1;
}else{
printf("Window created successfully!\n");
}
glfwMakeContextCurrent(window);
//Initialize GLEW
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to initialize glew!\n");
return 1;
}else{
printf("Successfully initialized glew!\n");
}
//Set the swap interval to 1 millisecond
glfwSwapInterval(1);
//Set the vertices of the square
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
//Set indices to make the square work
GLuint indices[] = {
0, 2, 1,
0, 3, 2
};
//Ignore this - it was the original square, but then I realized how I actually needed to make it work
float VerticesSquare[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
printf("GLfloat variable called successfully\n");
//Create, compile and link the shaders to the shader program
GLuint ShaderProgram = glCreateProgram();
GLuint ShaderObjv = glCreateShader(GL_VERTEX_SHADER);
GLuint ShaderObjf = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* pvs[1];
const GLchar* pfs[1];
//Set the shader code
const char* pVertexShaderText = "#version 330 core\n"
"layout(location = 0) in vec3 Position;\n"
"layout(location = 1) in vec3 incolor;\n"
"layout(location = 2) in vec2 Tex;\n"
"out vec3 outcolor;\n"
"out vec2 texcoords;\n"
"uniform uint xp;\n"
"uniform uint yp;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 proj;\n"
"void main(){\n"
" gl_Position = proj * view * model * vec4(Position, 1.0f);\n"
"outcolor = incolor;\n"
"texcoords = Tex;\n"
"}";
const char* pFragmentShaderText = "#version 330 core\n"
"uniform vec3 color;\n"
"uniform sampler2D tex0;\n"
"in vec3 outcolor;\n"
"in vec2 texcoords;\n"
"out vec4 FragColor;\n"
"void main(){\n"
" FragColor = vec4(outcolor, 1.0f);\n"
"}";
pvs[0] = pVertexShaderText;
pfs[0] = pFragmentShaderText;
GLint LenghtsVertex[1];
GLint LenghtsFragment[1];
LenghtsVertex[0] = strlen(pVertexShaderText);
LenghtsFragment[0] = strlen(pFragmentShaderText);
glShaderSource(ShaderObjv, 1, pvs, LenghtsVertex);
glShaderSource(ShaderObjf, 1, pfs, LenghtsFragment);
glCompileShader(ShaderObjv);
glCompileShader(ShaderObjf);
//Shader error handling
GLint successvs;
glGetShaderiv(ShaderObjv, GL_COMPILE_STATUS, &successvs);
if(!successvs){
GLchar InfoLog1[1024];
glGetShaderInfoLog(ShaderObjv, sizeof(InfoLog1), NULL, InfoLog1);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog1);
return 1;
}
GLint successfs;
glGetShaderiv(ShaderObjf, GL_COMPILE_STATUS, &successfs);
if(!successfs){
GLchar InfoLog2[1024];
glGetShaderInfoLog(ShaderObjf, sizeof(InfoLog2), NULL, InfoLog2);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_FRAGMENT_SHADER, InfoLog2);
return 1;
}
glAttachShader(ShaderProgram, ShaderObjv);
glAttachShader(ShaderProgram, ShaderObjf);
glLinkProgram(ShaderProgram);
GLint success;
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &success);
if(!success){
GLchar InfoLog3[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog3), NULL, InfoLog3);
fprintf(stderr, "Error linking shader program: '%s'\n", InfoLog3);
return 1;
}
glValidateProgram(ShaderProgram);
GLint successl;
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &successl);
if(!successl){
GLchar InfoLog4[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog4), NULL, InfoLog4);
fprintf(stderr, "Error validating shader program: '%s'\n", InfoLog4);
return 1;
}
glUseProgram(ShaderProgram);
//Set the vectors for the camera location
vec3 camerapos = {0.0f, 0.0f, -4.0f};
vec3 center = {0.0f, 0.0f, 0.0f};
vec3 yup = {0.0f, 1.0f, 0.0f};
//Create the matrices and make them be identity matrices
mat4 model;
mat4 view;
mat4 proj;
glm_mat4_identity(model);
glm_mat4_identity(view);
glm_mat4_identity(proj);
//Create the camera
glm_lookat(camerapos, center, yup, view);
glm_perspective(glm_rad(45.0f), (float)(width/height), 0.1f, 100.0f, proj);
//Set the uniform locations
GLint uniColor = glGetUniformLocation(ShaderProgram, "color");
GLint tex0uni = glGetUniformLocation(ShaderProgram, "tex0");
GLint xploc = glGetUniformLocation(ShaderProgram, "xp");
GLint yploc = glGetUniformLocation(ShaderProgram, "yp");
GLint modelloc = glGetUniformLocation(ShaderProgram, "model");
GLint viewloc = glGetUniformLocation(ShaderProgram, "view");
GLint projloc = glGetUniformLocation(ShaderProgram, "proj");
//Set the uniforms
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
glUniform1i(tex0uni, 0);
glUniform1ui(xploc, 1);
glUniform1ui(yploc, 1);
glUniformMatrix4fv(modelloc, 1, GL_FALSE, (float*)model);
glUniformMatrix4fv(viewloc, 1, GL_FALSE, (float*)view);
glUniformMatrix4fv(projloc, 1, GL_FALSE, (float*)proj);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Create the buffers
GLuint VBO;
GLuint VAO = 0;
GLuint EBO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
printf("Buffer created successfully\n");
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
printf("Buffer data set up successfully\n");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
printf("Enabling buffer successfull\n");
//Set the texture (I won't be using it for now)
int texwidth, texheight, texnum;
stbi_set_flip_vertically_on_load(true);
unsigned char* bytes = stbi_load("image.png", &texwidth, &texheight, &texnum, 0);
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float flatcolor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatcolor);
printf("Set parameters successfully\n");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texwidth, texheight, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
printf("Texture set successfully\n");
//Set the VertexAttribPointers at locations 0, 1 and 2
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
printf("First pointer succeeded\n");
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
printf("Second pointer succeeded\n");
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
printf("Third pointer succeeded\n");
printf("Setting up VectexAttribPointer successfull\n");
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//glDrawArrays(GL_TRIANGLES, 0, 3);
//Draw the elements
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
GLenum err;
if((err = glGetError()) != GL_NO_ERROR){
printf("OpenGL error: %d\n", err);
}
glfwSwapBuffers(window);
}
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if(key == GLFW_KEY_R && action == GLFW_PRESS){
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
}else if(key == GLFW_KEY_G && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 1.0f, 0.0f);
}else if(key == GLFW_KEY_B && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 0.0f, 1.0f);
}else if(key == GLFW_KEY_D && action == GLFW_PRESS){
glUniform1ui(xploc, 2);
}else if(key == GLFW_KEY_A && action == GLFW_PRESS){
glUniform1ui(xploc, 1);
}
}
I searched cglm's documentation, but didn't find a fix. There were some old stackoverflow questions on similar topics, but none actually solved my problem. I figured it has something to do with how I supply information to cglm's functions. I added comments, so it is easier to read.
As it turns out (float)(width/height) was supposed to be (float)width/(float)height as the first example was actually outputting 0 or 1, rather than 0.99716177861.
I created a small scene in C and OpenGL. It is a plane with a small tunnel over it. I'm trying to move the OpenGL "camera" inside this tunnel. However, I've been having some difficult to configure perspective and the objects disapear as I translate the object (my idea was to rotate and translate the scene to enter the tunnel).
I'm trying not to use additional lybraies, such as GLUT.
Can someone help?
#include <windows.h>
#include <gl/gl.h>
#define sizeX 0.05f
#define sizeY 0.75f
#define incr 0.1
double xyz[3] = {0,0,0};
int op = 0;
void incrAxis(int v){
if(v != 0)
xyz[op] += incr;
else
xyz[op] -= incr;
printf("%f %f %f\n",xyz[0],xyz[1],xyz[2]);
}
void changeAxis(int v){
op = op + v;
if(op == 3)
op = 0;
else
if(op < 0)
op = 2;
}
void draw(){
double alt = -0.1;
glBegin(GL_QUADS);
glColor3f(0.5f, 0.5f, 0.5f); // black plane
glVertex3f( 0.275, 0.275, alt);
glVertex3f( 0.275,-0.275, alt);
glVertex3f(-0.275,-0.275, alt);
glVertex3f(-0.275, 0.275, alt);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f); // plane
glVertex3f( 0.75, 0.75, 0.0f);
glVertex3f( 0.75,-0.75, 0.0f);
glVertex3f(-0.75,-0.75, 0.0f);
glVertex3f(-0.75, 0.75, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f( sizeX, sizeY, -sizeX);
glVertex3f( sizeX,-sizeY, -sizeX);
glVertex3f(-sizeX,-sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, -sizeX);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-sizeX, -sizeY, 0.0f);
glVertex3f(-sizeX, -sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(sizeX, -sizeY, 0.0f);
glVertex3f(sizeX, -sizeY, -sizeX);
glVertex3f(sizeX, sizeY, -sizeX);
glVertex3f(sizeX, sizeY, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-sizeX, sizeY, 0.0f);
glVertex3f(-sizeX, sizeY, -sizeX);
glVertex3f( sizeX, sizeY, -sizeX);
glVertex3f( sizeX, sizeY, 0.0f);
glEnd();
}
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hwnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
if (!RegisterClassEx(&wcex))
return 0;
/* create main window */
hwnd = CreateWindowEx(0,
"GLSample",
"OpenGL Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
512,
512,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
/* enable OpenGL for the window */
EnableOpenGL(hwnd, &hDC, &hRC);
/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
/* OpenGL animation code goes here */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(xyz[0],xyz[1],xyz[2]);
glRotatef(89, 1.0f, 0.0f, 0.0f);
glRotatef(50, 0.0f, 1.0f, 0.0f);
//glRotatef(5, 0.0f, 0.0f, 1.0f);
draw();
glPopMatrix();
SwapBuffers(hDC);
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL(hwnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow(hwnd);
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_RIGHT:
changeAxis(+1);
break;
case VK_DOWN:
incrAxis(0);
break;
case VK_LEFT:
changeAxis(-1);
break;
case VK_UP:
incrAxis(1);
break;
}
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC(hwnd);
/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glClearDepth(1.0); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//Realy Nice perspective calculations
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum(-10, 10, -10, 10, -100, 100);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}
I already solved the problem.
I replaced
glFrustum(-10, 10, -10, 10, -100, 100);
for
gluPerspective(45.0,1.0,0.1,200.0);
It now works fine.
I am stuck trying to get this code to work in Visual Studio 2012 using glut. It renders a 10/10 3D grid but it will not respond to my input from the keyboard. I am trying to get the camera to rotate around the origin when i hit the left arrow key.
// This example shows how to create a camera for 3D graphics.
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int g_winWidth = 1024;
int g_winHeight = 512;
bool keyStatus[256];
float angle = 0.0f; //angle for rotating camera
float beginning_angle = 0.0f;
float cx = 10.0, cy = 10.0, cz = -10.0;
void initialGL()
{
glEnable(GL_DEPTH_TEST);
glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
//initialize the keyboard keys
void initialization()
{
for(int i =0; i<256; i++)
keyStatus[i] = false;
}
//function to draw the colored x,y, and z axis
void drawCS()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(10.0f, 10.0f, 10.0f);
glLineWidth(2.5f);
glBegin(GL_LINES);
//axis x
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.3f, 0.0f, 0.0f);
//text x
glVertex3f(0.4f, 0.05f, 0.0f);
glVertex3f(0.5f, -0.05f, 0.0f);
glVertex3f(0.4f, -0.05f, 0.0f);
glVertex3f(0.5f, 0.05f, 0.0f);
//axis y
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.3f, 0.0f);
//text y
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.0f, 0.4f, 0.0f);
glVertex3f(-0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
//axis z
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.3f);
//text z
glVertex3f(-0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(0.025f, -0.025f, 0.4f);
glEnd();
glLineWidth(1.0f);
glPopMatrix();
}
//function to draw the grid
void drawGrid()
{
int size = 10; // determining the grid size and the numbers of cells
if(size%2 != 0) ++size;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glScalef(30.0f, 30.0f, 30.0f);
glBegin(GL_LINES);
for (int i =0; i<size+1; i++) {
if((float)i == size/2.0f) {
glColor3f(0.0f, 0.0f, 0.0f);
} else {
glColor3f(0.8f, 0.8f, 0.8f);
}
glVertex3f(-size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(-size/2.0f+i, 0.0f, -size/2.0f);
glVertex3f(-size/2.0f+i, 0.0f, size/2.0f);
}
glEnd();
glPopMatrix();
}
//function to display everything that is happening in window
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawGrid();// call to function to draw the grid
drawCS();//call to function to draw the x,y,z axis
glutSwapBuffers();
}
void reshape(int w, int h)
{
g_winWidth = w;
g_winHeight = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//this function sets the initial position of the camera in 3D space
/*
Need to find a way to rotate around the origin from left to right
*/
gluLookAt( cx, cy, cz, //camera position
0.0f, 0.0f, 0.0f, //what camera looks at
0.0f, 1.0f, 0.0f); //
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, g_winWidth/g_winHeight, 0.1, 100);//specifies the view for the scene
glViewport(0, 0, w, h);
//angle += 0.1f;
}
//keyboard function for the exit key
void keyboard(unsigned char key, int x, int y)
{
keyStatus[key] = true;
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
//sets the keyboard callback to the current window
void keyboardUp(unsigned char key, int x, int y)
{
keyStatus[key] = false;
}
//function for arrow keys output
void processSpecialKeys(int key, int xx, int yy) {
switch(key) {
case GLUT_KEY_LEFT :
//What the left arrow key does
angle -= 0.01f;
cx = sin(angle);
cz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
//What the right arrow key does
break;
case GLUT_KEY_UP :
//What the up arrow key does
break;
case GLUT_KEY_DOWN :
//What the down arrow key does
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(g_winWidth, g_winHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Camera");
initialGL();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(processSpecialKeys);
glEnable(GL_DEPTH_TEST);
initialization();
glutMainLoop();
return 1;//changed from EXIT_SUCCESS
}
I hope to create an offScreen FBO, and use glReadPixels() to get the value of RGBA in this offScreen FBO. unfortunately, I got the error: GL_ERROR:0x0502
#import "ViewController.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
#interface ViewController ()
{
GLuint backFBO;
GLuint defaultFBO;
int fbo_width;
int fbo_height;
//
GLuint _vertexArray;
GLuint _vertexBuffer;
GLuint _texCoordBuffer;
GLuint depthBuffer;
//
GLKMatrix4 _modelViewProjectionMatrix;
GLKMatrix3 _normalMatrix;
float _rotation;
}
#property (nonatomic, strong) GLKBaseEffect *baseEffect;
#property (nonatomic, strong) EAGLContext *context;
- (void)setupGL;
- (void)tearDownGL;
- (void)setupFBO;
#end
the vertex data and normal data of object in onScreen FBO
GLfloat gVertexData[] =
{
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//1. setup context
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
];
if (!self.context) {
NSLog(#"Failed to create GLES Context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[self tearDownGL];
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
self.context = nil;
}
- (void) setupGL
{
[EAGLContext setCurrentContext:self.context];
self.baseEffect = [[GLKBaseEffect alloc] init];
glEnable(GL_DEPTH_TEST);
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gVertexData), gVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);
// initialize FBO
[self setupFBO];
}
- (void) tearDownGL
{
[EAGLContext setCurrentContext:self.context];
glDeleteBuffers(1, &_vertexBuffer);
}
- (void)update
{
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.baseEffect.transform.projectionMatrix = projectionMatrix;
// Compute the model view matrix for the object rendered with ES2
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -2.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
self.baseEffect.transform.modelviewMatrix = modelViewMatrix;
_rotation += self.timeSinceLastUpdate * 0.5f;
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
// render FBO tex
[self renderFBO];
// reset to main framebuffer
[((GLKView *) self.view) bindDrawable];
glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
// render main
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
[self.baseEffect prepareToDraw];
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
#pragma mark - FBO
// intialize FBO
- (void)setupFBO
{
fbo_width = 512;
fbo_height = 512;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
NSLog(#"default FBO: %d", defaultFBO);
glGenFramebuffers(1, &backFBO);
glGenRenderbuffers(1, &depthBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, backFBO);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, fbo_width, fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
// FBO status check
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
NSLog(#"fbo complete");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
NSLog(#"fbo unsupported");
break;
default:
/* programming error; will fail on all hardware */
NSLog(#"Framebuffer Error");
break;
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
}
// render FBO
- (void)renderFBO
{
glBindFramebuffer(GL_FRAMEBUFFER, backFBO);
glViewport(0,0, fbo_width, fbo_height);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
**//in here, I hope to get the value of RGBA in offScreen FBO**
Byte pixelColor[4] = {0,};
glReadPixels(50, 50, fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_BYTE, pixelColor);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
}
when I comment glReadPixels(), it's works well. Any help or advice would be much appreciated.
in your offScreen FBO, you should bind a GL_RENDERBUFFER, so you should add below code:
//create a new FBO
glBindFramebuffer(GL_FRAMEBUFFER, backFBO);
// add
GLuint _colorBuffer;
glGenRenderbuffers(1, &_colorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, fbo_width , fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER, _colorBuffer);
I hope this will fix your error. good luck !!!
the purpose of my program is to load and display a simple cube with the same texture on each face. the problem is the 2 first faces (front, rear) are good. I tried several combinations of vertices in the textures array but it doesn't work. I don't know if I need to add more vertices in the textures array or change the order or change the indices array.
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float vertices[] =
{
-1.0f, -1.0f, 1.0f, // 0
1.0f, -1.0f, 1.0f, // 1
-1.0f, 1.0f, 1.0f, // 2
1.0f, 1.0f, 1.0f, // 3
-1.0f, -1.0f, -1.0f,// 4
1.0f, -1.0f, -1.0f, // 5
-1.0f, 1.0f, -1.0f, // 6
1.0f, 1.0f, -1.0f, // 7
};
GLubyte indices[] =
{
0,1,2, 1,3,2, //front face
6,7,5, 6,5,4, //rear face
1,5,3, 5,7,3, //problem on the right face
//2,3,6, 3,6,7,
//2,4,0, 2,4,6
0,5,1, 5,4,0
};
float textures[] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glBindTexture(GL_TEXTURE_2D, texCube);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(90.0f, 1.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textures);
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}
Your corners are sharing texture coordinates, which just isn't going to work.
you should have 4 vertices for each face, as the texture coordinates for each corner will be different depending on the face.
The solution of my problem is the following code :
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float angle = 0.0f;
float vertices[72] =
{
-1.0f, -1.0f, 1.0f,//VO - 0
1.0f, -1.0f, 1.0f,//V1 - 1
-1.0f, 1.0f, 1.0f,//V2 - 2
1.0f, 1.0f, 1.0f,//V3 - 3
-1.0f, -1.0f, -1.0f,//V4 - 4
1.0f, -1.0f, -1.0f,//V5 - 5
-1.0f, 1.0f, -1.0f,//V6 - 6
1.0f, 1.0f, -1.0f,//V7 - 7
-1.0f, 1.0f, 1.0f,//V2 - 8
1.0f, 1.0f, 1.0f,//V3 - 9
-1.0f, 1.0f, -1.0f,//V6 - 10
1.0f, 1.0f, -1.0f,//V7 - 11
-1.0f, -1.0f, 1.0f,//VO - 12
1.0f, -1.0f, 1.0f,//V1 - 13
-1.0f, -1.0f, -1.0f,//V4 - 14
1.0f, -1.0f, -1.0f,//V5 - 15
-1.0f, -1.0f, 1.0f,//VO - 16
-1.0f, 1.0f, 1.0f,//V2 - 17
-1.0f, -1.0f, -1.0f,//V4 - 18
-1.0f, 1.0f, -1.0f,//V6 - 19
1.0f, -1.0f, 1.0f,//V1 - 20
1.0f, 1.0f, 1.0f,//V3 - 21
1.0f, -1.0f, -1.0f,//V5 - 22
1.0f, 1.0f, -1.0f,//V7 - 23
};
GLubyte indices[36] =
{
0,1,2, 1,3,2,
6,7,5, 6,5,4,
8,9,10, 9,10,11,
12,13,14, 13,14,15,
17,16,18, 17,18,19,
20,21,22, 21,22,23
};
float textures[48] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glBindTexture(GL_TEXTURE_2D, texCube);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(angle, 1.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textures);
glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_BYTE, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
angle += 1.0f;
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}
And the solution with VBO :
#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)
float angle = 0.0f;
float vertices[72] =
{
-1.0f, -1.0f, 1.0f,//VO - 0
1.0f, -1.0f, 1.0f,//V1 - 1
-1.0f, 1.0f, 1.0f,//V2 - 2
1.0f, 1.0f, 1.0f,//V3 - 3
-1.0f, -1.0f, -1.0f,//V4 - 4
1.0f, -1.0f, -1.0f,//V5 - 5
-1.0f, 1.0f, -1.0f,//V6 - 6
1.0f, 1.0f, -1.0f,//V7 - 7
-1.0f, 1.0f, 1.0f,//V2 - 8
1.0f, 1.0f, 1.0f,//V3 - 9
-1.0f, 1.0f, -1.0f,//V6 - 10
1.0f, 1.0f, -1.0f,//V7 - 11
-1.0f, -1.0f, 1.0f,//VO - 12
1.0f, -1.0f, 1.0f,//V1 - 13
-1.0f, -1.0f, -1.0f,//V4 - 14
1.0f, -1.0f, -1.0f,//V5 - 15
-1.0f, -1.0f, 1.0f,//VO - 16
-1.0f, 1.0f, 1.0f,//V2 - 17
-1.0f, -1.0f, -1.0f,//V4 - 18
-1.0f, 1.0f, -1.0f,//V6 - 19
1.0f, -1.0f, 1.0f,//V1 - 20
1.0f, 1.0f, 1.0f,//V3 - 21
1.0f, -1.0f, -1.0f,//V5 - 22
1.0f, 1.0f, -1.0f,//V7 - 23
};
GLubyte indices[36] =
{
0,1,2, 1,3,2,
6,7,5, 6,5,4,
8,9,10, 9,10,11,
12,13,14, 13,14,15,
17,16,18, 17,18,19,
20,21,22, 21,22,23
};
float textures[48] =
{
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
0.0f, 1.0f,//0
1.0f, 1.0f,//1
0.0f, 0.0f,//2
1.0f, 0.0f,//3
};
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Texture Mapping",NULL);
SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);
bool continuer = true;
SDL_Event event;
GLuint texCube;
GLuint VBO[3];
glClearDepth(1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
glewInit();
texCube = loadTexture("caisse.jpg");
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(textures), textures, GL_STATIC_DRAW);
glEnable(GL_TEXTURE_2D);
while (continuer)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
//Draw Cube ---------------------------------------
glPushMatrix();
glRotatef(angle, 1.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, texCube);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glVertexPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glTexCoordPointer(2, GL_FLOAT, 0, OFFSET_BUFFER(0));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_BYTE, OFFSET_BUFFER(0));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//-------------------------------------------------
angle += 1.0f;
glPopMatrix();
glFlush();
SDL_GL_SwapBuffers();
}
glDisable(GL_TEXTURE_2D);
SDL_Quit();
return 0;
}
If you really want to save a few bytes, you can still factorize a few vertices (16 vertices instead of 24). You consider your cube without two opposite faces and add these two faces separately. Here is an IQM model which does just that:
# Inter-Quake Export
mesh "Cube"
material "cube.tga"
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp 1 -1 -1
vn 1 -1 -1
vt 0 1
vp -1 -1 -1
vn -1 -1 -1
vt 1 1
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp 1 1 1
vn 1 1 1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 0 0
vp -1 -1 1
vn -1 -1 1
vt 0 1
vp 1 -1 1
vn 1 -1 1
vt 1 1
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 1 1
vp 1 1 1
vn 1 1 1
vt 0 1
vp 1 1 -1
vn 1 1 -1
vt 0 0
vp -1 1 -1
vn -1 1 -1
vt 1 0
vp -1 1 1
vn -1 1 1
vt 1 1
vp 1 1 1
vn 1 1 1
vt 0 1
fm 0 1 2
fm 0 2 3
fm 0 4 7
fm 0 7 1
fm 4 6 7
fm 4 5 6
fm 5 2 6
fm 5 3 2
fm 8 9 10
fm 8 10 11
fm 12 15 14
fm 12 14 13