Related
I am trying to draw a cube with different colors on each face using OpenGL ES 2.0. I can only draw a cube in one color now. I knew I need to use VertexAttribPointer in this case instead of Uniform, but I probably added them wrongly. Screen shows nothing after I implement my code. Here is my code, can anybody give me a hand? Thank you so much!!!
public class MyCube {
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;
private ShortBuffer[] ArrayDrawListBuffer;
private FloatBuffer colorBuffer;
private int mProgram;
//For Projection and Camera Transformations
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}";
// Use to access and set the view transformation
private int mMVPMatrixHandle;
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
float cubeCoords[] = {
-0.5f, 0.5f, 0.5f, // front top left 0
-0.5f, -0.5f, 0.5f, // front bottom left 1
0.5f, -0.5f, 0.5f, // front bottom right 2
0.5f, 0.5f, 0.5f, // front top right 3
-0.5f, 0.5f, -0.5f, // back top left 4
0.5f, 0.5f, -0.5f, // back top right 5
-0.5f, -0.5f, -0.5f, // back bottom left 6
0.5f, -0.5f, -0.5f, // back bottom right 7
};
// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
float red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
float blue[] = { 0.0f, 0.0f, 1.0f, 1.0f };
private short drawOrder[] = {
0, 1, 2, 0, 2, 3,//front
0, 4, 5, 0, 5, 3, //Top
0, 1, 6, 0, 6, 4, //left
3, 2, 7, 3, 7 ,5, //right
1, 2, 7, 1, 7, 6, //bottom
4, 6, 7, 4, 7, 5};//back (order to draw vertices)
final float[] cubeColor =
{
// Front face (red)
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,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
// Top face (green)
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,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
// Left face (blue)
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,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
// Right face (yellow)
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,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
// Bottom face (cyan)
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,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
// Back face (magenta)
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,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f
};
public MyCube() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
cubeCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(cubeCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// initialize byte buffer for the color list
ByteBuffer cb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
cubeColor.length * 4);
cb.order(ByteOrder.nativeOrder());
colorBuffer = cb.asFloatBuffer();
colorBuffer.put(cubeColor);
colorBuffer.position(0);
int vertexShader = MyRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
}
private int mPositionHandle;
private int mColorHandle;
private final int vertexCount = cubeCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Enable a handle to the cube vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the cube coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// Set color for drawing the triangle
//mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Enable a handle to the cube colors
GLES20.glEnableVertexAttribArray(mColorHandle);
// Prepare the cube color data
GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, 16, colorBuffer);
// Set the color for each of the faces
//GLES20.glUniform4fv(mColorHandle, 1, blue, 0);
//***When I add this line of code above, it can show a cube totally in blue.***
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Draw the cube
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mColorHandle);
GLES20.glDisableVertexAttribArray(mMVPMatrixHandle);
}
}
Remove the uniform variable vColor declaration from the fragment shader. Define the new per-vertex attribute input variable in the vertex shader, write that value to a varying variable which is output by the vertex shader, and add as a varying input which is read by the fragment shader.
I am trying to setup my Vertices and Texture Coordinates such that I have a single Quad ( 2 triangles ) covering the entire OpenGL Window. I want to then update the texture as I receive images from my camera.
It is working except for that my streaming texture never fills the entire screen and the texture pixels are repeated outside of the intended texture ( see images below ).
How do I setup my vertices and texture coordinates so that my texture will fill the quad without repeating?
Here is how I generate my texture:
glGenTextures(1, &m_dataFrame);
glBindTexture(GL_TEXTURE_2D, m_dataFrame);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame.bits());
// CUSTOM
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Initial Attempts:
// Setup the vertices and texture coordinates
float scaler = 1.0f;
static const GLfloat squareVertices[] = {
-(1.0f/scaler), -(1.0f/scaler), 0.0f, // First triangle bottom left
(1.0f/scaler), -(1.0f/scaler), 0.0f,
-(1.0f/scaler), (1.0f/scaler), 0.0f,
(1.0f/scaler), -(1.0f/scaler), 0.0f, // Second triangle bottom right
(1.0f/scaler), (1.0f/scaler), 0.0f,
-(1.0f/scaler), (1.0f/scaler), 0.0f,
};
static const GLfloat textureVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, 1.0f,
};
This results in the following image:
// Setup the vertices and texture coordinates
float x = 1.0f;
float y = 1.0f;
static const GLfloat squareVertices[] = {
-(x*2), -(y*2), 0.0f, // First triangle bottom left
(x*2), -(y*2), 0.0f,
-(x*2), (y*2), 0.0f,
(x*2), -(y*2), 0.0f, // Second triangle bottom right
(x*2), (y*2), 0.0f,
-(x*2), (y*2), 0.0f,
};
static const GLfloat textureVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, 1.0f,
};
This results in the following image:
This is what I've used for rendering a textured quad on the Raspberry Pi (in Swift, but the syntax is similar to what you'd use for C). Setting up the texture parameters:
glEnable(GLenum(GL_TEXTURE_2D))
glGenTextures(1, &cameraOutputTexture)
glActiveTexture(GLenum(GL_TEXTURE0));
glBindTexture(GLenum(GL_TEXTURE_2D), cameraOutputTexture)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_NEAREST)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_NEAREST)
uploading the texture:
glActiveTexture(GLenum(GL_TEXTURE0))
glBindTexture(GLenum(GL_TEXTURE_2D), cameraOutputTexture)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, 1280, 720, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), buffers[Int(currentBuffer)].start)
and rendering it:
glClear(GLenum(GL_COLOR_BUFFER_BIT))
shader.use()
let squareVertices:[GLfloat] = [
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
1.0, 1.0,
]
let textureCoordinates:[GLfloat] = [
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
]
glVertexAttribPointer(positionAttribute, 2, GLenum(GL_FLOAT), 0, 0, squareVertices)
glVertexAttribPointer(textureCoordinateAttribute, 2, GLenum(GL_FLOAT), 0, 0, textureCoordinates)
glUniform1i(GLint(textureCoordinateAttribute), 1)
glDrawArrays(GLenum(GL_TRIANGLE_STRIP), 0, 4)
eglSwapBuffers(display, surface)
I might be rotating the image to account for rotation in the camera that I'm using as an input source, so you may need to tweak the vertices or coordinates if you see your image rendering upside-down.
I'm getting started with OpenGL. I need to do a project using glaux.h. My problem is that I'm running Mac OS X Lion, so I cannot use glaux.
I was searching on the web and I found some codes that try to replace glaux. Codes were fine, but they use Windows Api variables. So obviously I can't use them. Here is the code that I need to read using glaux:
#include <stdio.h> // Header File For Standard Input/Output
#include <stdlib.h>
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include "bmp.h"
#include <string.h>
const int W_WIDTH = 500; // PreselecciÛn del ancho de la ventana
const int W_HEIGHT = 500; // PreselecciÛn del alto de la ventana
bool keys[256]; // Array Used For The Keyboard Routine
bool active=1; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
bool fullscreen=0; // Fullscreen Flag Set To Fullscreen Mode By Default
GLuint texture[1]; // Storage For 1 Texture
GLuint box; // Storage For The Box Display List
GLuint top; // Storage For The Top Display List
GLuint xloop; // Loop For X Axis
GLuint yloop; // Loop For Y Axis
GLfloat xrot; // Rotates Cube On The X Axis
GLfloat yrot; // Rotates Cube On The Y Axis
static GLfloat boxcol[5][3]=
{
{1.0f,0.0f,0.0f},{1.0f,0.5f,0.0f},{1.0f,1.0f,0.0f},{0.0f,1.0f,0.0f},{0.0f,1.0f,1.0f}
};
static GLfloat topcol[5][3]=
{
{.5f,0.0f,0.0f},{0.5f,0.25f,0.0f},{0.5f,0.5f,0.0f},{0.0f,0.5f,0.0f},{0.0f,0.5f,0.5f}
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
// Build Cube Display Lists
GLvoid BuildLists()
{
box=glGenLists(2); // Generate 2 Different Lists
glNewList(box,GL_COMPILE); // Start With The Box List
glBegin(GL_QUADS);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
top=box+1; // Storage For "Top" Is "Box" Plus One
glNewList(top,GL_COMPILE); // Now The "Top" Display List
glBegin(GL_QUADS);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
}
AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image
{
FILE *File=NULL; // File Handle
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}
File=fopen(Filename,"r"); // Check To See If The File Exists
if (File) // Does The File Exist?
{
fclose(File); // Close The Handle
return new AUX_RGBImageRec(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=0; // Status Indicator
char ruta[100]="Data/Cube.bmp";
AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if (TextureImage[0]==LoadBMP(ruta))
{
Status=1; // Set The Status To TRUE
glGenTextures(1, &texture[0]); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); // Free The Texture Image Memory
}
free(TextureImage[0]); // Free The Image Structure
}
return Status; // Return The Status
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL() // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return 0; // If Texture Didn't Load Return FALSE
}
BuildLists(); // Jump To The Code That Creates Our Display Lists
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable(GL_COLOR_MATERIAL); // Enable Material Coloring
return 1; // Initialization Went OK
}
void DrawGLScene() // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear The Screen And The DepthB
glBindTexture(GL_TEXTURE_2D, texture[0]);
for (yloop=1;yloop<6;yloop++)
{
for (xloop=0;xloop<yloop;xloop++)
{
//Poner vuestro codigo no hace falta que se ve axactamente igual
}
}
// Vacia los buffers de dibujo
glutSwapBuffers();
glFlush();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitWindowPosition(100,100);
glutInitWindowSize (W_WIDTH, W_HEIGHT);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Ventana con el Visual C++ y glut");
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
// Funciones de inicializacion
InitGL();
glutMainLoop();
return 0;
}
Now that GLKit is available on OS X, I suggest you give that a look. Erik Buck's book Learning OpenGL ES for iOS is written around that framework, with an iOS focus, but he has a blog post and sample project showing a port to OS X 10.8.
Another idea, if you're allowed to step back from OpenGL, is to use SceneKit. It's a 10.8 only framework, not available on any platform other than Mac. It exposes most of the same controls that you have in OpenGL, but it is fundamentally an Objective-C, object-based design, and integrates well with Core Animation. Documentation is sparse but it's pretty easy to get things running. I found it much easier to wrap my brain around SceneKit than around OpenGL. Best intro is the WWDC 2012 video.
I am trying to understand the perspective view in OpenGL.
What I am trying to do is render two identical triangles, but at different z coordinates, so I assume they should appear at different sizes. Here is my code:
CUSTOMVERTEX Vertices[] =
{
{ 0.5f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f }, // x, y, z, color
{ 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
};
and for drawing
glDrawArrays(GL_TRIANGLES,0, 3);
glTranslatef(0.0f,-1.0f,-1.5f);
glDrawArrays(GL_TRIANGLES,0, 3);
and here is how I init some attributes
glShadeModel(GL_SMOOTH);
glClearDepthf(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
but the triangles appear at the same size, just at different locations as I translated Y.
Can someone please explain to me?
You cannot use 0.0 for the perspective projection's near-Z value. It must be a positive number greater than zero. Preferably on the order of 1.0 or so.
As Nicol said you should use numbers greater than 0 for frustrum construction. I strongly suggest you to read this article to understand why it is so.
I have a curious problem about an App which MainView is inherited from NSOpenGlView.
I am able to draw many things in it, like a basic OpenGL tutorial.... but when I try to implement a basic trackball, it looks like the app waits until I release the mouse button before it refreshes my view... even if I call directly the "DrawRect" callback from the "MouseDragged" callback, it acts the same. Then, I really can't find out how to do such a basic thing and what is the problem about my solution..
Any idea?
My NSOpenGLVIew has double buffer, and and additional depth buffer.
Here are the main messages.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)mouseDragged:(NSEvent *)theEvent {
//[[self openGLContext] makeCurrentContext];
float curPos[3], dx, dy, dz;
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];
angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
//glutPostRedisplay();
//[self drawRect:self.bounds]; // different attempts
[self setNeedsDisplay:YES]; //
//[self display];
}
#pragma mark Mouse Handling
- (void)mouseDown:(NSEvent *)theEvent {
m_PreviousMouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
ptov(m_PreviousMouseLoc.x,m_PreviousMouseLoc.y,m_width,m_height,lastPos);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)mouseUp:(NSEvent *)theEvent {
[self setNeedsDisplay:YES];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ptov(int x, int y, int width, int height, float v[3]){
float a,d;
// project x,y onto 1/2 sphere centered within width and height
v[0] = (2.0*x - width)/ width;
v[1] = (height - 2.0*y)/ height;
d = sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = cos((PI/2)*((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *=a;
v[1] *=a;
v[2] *=a;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-(void)prepareOpenGL{
if( ![ self loadGLTextures ] ){
NSLog(#"Failed to load GL Textures");
}
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
//glEnable( GL_TEXTURE_2D ); // Enable texture mapping
glShadeModel( GL_SMOOTH ); // Enable smooth shading
glClearColor( 0.0f, 0.0f, 0.0f, 0.5f ); // Black background
glClearDepth( 1.0f ); // Depth buffer setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable (GL_BLEND);
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonOffset (1.0f, 1.0f);
firstOccurenceOfDrawRect = NO;
/* // set start values...
rVel[0] = 0.3; rVel[1] = 0.1; rVel[2] = 0.2;
rAccel[0] = 0.003; rAccel[1] = -0.005; rAccel[2] = 0.004;*/
[[self window] setAcceptsMouseMovedEvents: YES];
glViewport(0, 0, (GLsizei) self.bounds.size.width, (GLsizei) self.bounds.size.height);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void) drawRect: (NSRect) rect
{
/// if (firstOccurenceOfDrawRect)
// [self initGL];
// On charge la matrice de projection pour définir ce que l'on va voir et comment
glMatrixMode(GL_PROJECTION);
// On centre
glLoadIdentity();
// On prend du recul
glOrtho(-1.0f, 1.0f, -1.5f, 1.5f, -10.0f, 10.0f);
// On efface ce qui a été dessiné auparavant
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// On va maintenant définir ce que l'on veut dessiner
glMatrixMode(GL_MODELVIEW);
// Avant de commencer à dessiner, on va affecter de deux rotations le repère des coordonnées du cube pour le faire "bouger"
glLoadIdentity();
glRotatef(angle, axis[0], axis[1], axis[2]);
// [self resizeGL]; // forces projection matrix update (does test for size changes)
// [self updateModelView];
glColor3f (1.0, 1.0, 1.0);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CW);
glutSolidTeapot(200.0);
glFrontFace(GL_CCW);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture[ 0 ] ); // Select our texture
glBegin( GL_QUADS );
// Front
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, -1.0f, 0.0f ); // Bottom left
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, -1.0f, 0.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, 1.0f, 0.0f ); // Top right
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, 1.0f, 0.0f ); // Top left
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[ 1 ] ); // Select our texture
glBegin( GL_QUADS );
// side
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 0.0f, -1.0f, -1.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 0.0f, 1.0f, -1.0f ); // Top right
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( 0.0f, 1.0f, 1.0f ); // Top left
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( 0.0f, -1.0f, 1.0f ); // Bottom left
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[ 2 ] ); // Select our texture
glBegin( GL_QUADS );
// Top
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, 0.0f, -1.0f ); // Top left
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, 0.0f, 1.0f ); // Bottom left
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 1.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, 0.0f, -1.0f ); // Top right
glEnd();
glDisable(GL_TEXTURE_2D);
glColor3f (1.0, 1.0, 1.0);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CW);
glutSolidTeapot(200.0);
[self postRemoteImage];
[[self openGLContext] flushBuffer];
}
Is this the entire code for the relevant methods? If so, you're never grabbing the mouse's position when you're dragging. curPos[] is uninitialized and may be returning the same values for each time you get a mouseDragged: message. This may make your object always rotate to the same position, making it appear like it's not moving.
Try inserting an NSLog in your mouseDragged: method to make sure that it's being called for your mouse drags (it probably is, but it's good to check).
There's a slight possibility that you're not giving the main run loop a chance to refresh the display, but I think that's unlikely. I've done something similar in my code and had it work just fine with everything on the main thread.
Rather than rolling your own trackball implementation, I suggest looking at Bill Dudney's trackball example code. While it is for the iPhone and deals with Core Animation, the trackball object he uses should be applicable to your case.